HDU4394 Digital Square BFS搜索

这一题是给定一个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;
}
原文地址:https://www.cnblogs.com/Lyush/p/2678705.html