HDU-4394 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;

}

你可能感兴趣的:(git)