题解 | #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;
}
}