B3730 [信息与未来 2017] 密码锁
欢迎报名洛谷网校,期待和大家一起进步!
如果去模拟密码锁的拨动,那么完成这道题会很困难。不妨换个思路:枚举
首先是判断质数部分。判断质数需要注意
bool isPrime(int x) {
if (x < 2) return false;
for (int i = 2; i * i <= x; ++i)
if (x % i == 0) return false;
return true;
}
较为麻烦的部分是计算需要拨动多少次。首先考虑将枚举的
string to5D(int x) { // 转换为 5 位字符串
string ans = to_string(x);
while (ans.size() < 5) ans = "0" + ans;
return ans;
}
int totD(string x) { // 计算总拨动次数
int ans = 0;
for (int i = 0; i < 5; i++) {
int xi = x[i] - '0'; // 当前字符串的数字
int si = s[i] - '0'; // 初始字符串的数字
ans += digD(xi, si); // 计算要拨动多少次
}
return ans;
}
接下来考虑完成 digD 这个函数。拨动有两种方案,要从其中取最小值。例如说从
int digD(int x, int y) {
int diff = abs(x - y);
return min(diff, 10 - diff);
}
最后,将上面的代码装填入主函数的枚举过程中,根据计算的结果更新答案即可。
for (int i = 2; i < 100000; i++) {
if (isPrime(i)) {
string num = to5D(i);
int dist = totD(num);
if (dist <= minT) {
minT = dist;
bestP = i;
}
}
}