题解 | #J Luggage Lock#

Luggage Lock

https://ac.nowcoder.com/acm/contest/24346/J

题目:

转数字锁,每次选择相邻的加一位或减一位。然后给数字a, b问你用a最少次数转到b, 最少次数是多少

思路:

这里主要讲我的做法。赛时想到了对与每个数字,要么向前,要么想后,但是怎么交都是错的,赛后观察数据发现bug。对于每个数字,我们记录向前后向后的次数,然后由于只有4个数字,我们就可以直接枚举,就类似枚举子集。但是当数字相等的时候,无论向前或者向后,会有0或者10,这种情况也要记录。然后就用积木大赛的做法做

代码:

#include<bits/stdc++.h>
using namespace std;

int solve(vector<int> g, int n){
	int ans = 0;
	int pre = n&1;
	for(int i = 3; i >= 0; i--){
		if(i == 3){
			ans += g[i];
			n >>= 1;
			continue;
		}
		if((n&1) == pre){
			if(g[i] > g[i+1]){
				ans += g[i]-g[i+1];
			}
		}else{
			ans += g[i];
		}
		pre = n&1;
		n >>= 1;
	}
	return ans;
}

int main(){
	int t;
	cin >> t;
	while(t--){
		string a, b;
		cin >> a >> b;
		vector<int> v1(4, 0), v2(4, 0), v3(4, 0), v4(4, 0);
		for(int i = 0; i < 4; i++){
			v1[i] = (b[i]-a[i]+10)%10;
			v2[i] = 10-v1[i];
			if(a[i] == b[i]){
				v3[i] = 10;
				v4[i] = 0;
			}else{
				v3[i] = v1[i];
				v4[i] = v2[i];
			}
		}
		vector<int> tm(4, 0), tm1(4, 0);
		int ans = 0x3f3f3f3f;
		for(int i = 0; i < 16; i++){
			int x = i;
			for(int j = 3; j >= 0; j--){
				if(x & 1){
					tm[j] = v1[j];
					tm1[j] = v3[j];
				}else{
					tm[j] = v2[j];
					tm1[j] = v4[j];
				}
                x >>= 1;
			}
			ans = min(ans, solve(tm, i));
			ans = min(ans, solve(tm1, i));
		}
		cout << ans << endl;
	}
}
全部评论

相关推荐

喜欢喜欢喜欢:这是我见过最长最臭的简历
点赞 评论 收藏
分享
评论
4
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务