这一题是给定一个N,求一个最小的数M满足M^2%10^k = N,也就是M的平方的后面与N相同位数的数字的值为N。
对于这一题,我的思路就是BFS搜索,对于每一位,假设出一个数来使得其平方的结果逐步的逼近最终的结果。
代码如下:
#include <iostream> #include <cstdlib> #include <cstdio> #include <queue> #include <algorithm> using namespace std; // 假设N是一个5位数,那么最差情况时是由1个大于等于5位数的数的平方得到的 // 否则的话,就是一个4位数或者3位数构成的,因为一个x位的数,这个数的平方最大构成一个2*x位的数 int path[15], N, MOD; long long ans; long long get(long long &t) { t = 0; int p = 1; while (path[p] != -1) ++p; for (int i = p-1; i >= 1; --i) { t *= 10; t += path[i]; } return t * t; // 通过路径得到我们已经枚举到的数了 } int _pow(int a, int b) { int ret = 1; for (int i = 1; i <= b; ++i) { ret *= a; } return ret; } void dfs(int deep) { long long x, t; int mod = _pow(10, deep); for (int i = 0; i <= 9; ++i) { path[deep] = i; x = get(t); if (t / N >= 10) { path[deep] = -1; return; // 表示这个数已经超过N的长度,其不可能产生一个最优解 } if (x == N) { ans = min(ans, t); } else if (x % mod == N % mod){ if (x % MOD == N) { ans = min(ans, t); } else { dfs(deep+1); } } path[deep] = -1; } } int main() { int T, len; scanf("%d", &T); while (T--) { len = 0; scanf("%d", &N); int f = N; while (f) { ++len; f /= 10; } MOD = _pow(10, len); ans = 1LL << 60; memset(path, 0xff, sizeof (path)); dfs(1); if (ans == 1LL << 60) { puts("None"); } else { cout << ans << endl; } } return 0; }