一、内容
Given an integer N,you should come up with the minimum nonnegative integer M.M meets the follow condition: M 2%10 x=N (x=0,1,2,3....)
Input
The first line has an integer T( T< = 1000), the number of test cases.
For each case, each line contains one integer N(0<= N <=10 9), indicating the given number.
Output
For each case output the answer if it exists, otherwise print “None”.
Sample Input
3
3
21
25
Sample Output
None
11
5
二、思路
- 证明:N的后n位只与M的后n为有关。
- 当M只有一位C的时候, M2 = C2, 所以个位只与C有关。
- 当M有二位时,M = 10 * B +C, M2 = 100B2 + C2 + 10 * 2BC , 那么个位只与C有关,十位与BC有关。
- 当M有三位时,M = 100 * A + 10 * B + C , M2 = 10000A2 + 10002AB + 100 * (2AC + B2) + 10 2BC + C2 个位只与C有关,十位只与BC有关,百位只与ABC有关。
- 故根归纳法可证 :N的后n位只与M的后n为有关。
- 我们只需要从个位开始一位一位的进行搜索即可。每搜索一位,就对n的后缀就行对比,看已经搜索出来的位数是否相同,若相同继续下一位的搜索,直到找到结果。
三、代码
#include <cstdio>
#define min(a, b) (a > b ? b : a)
typedef long long ll;
static int INF = 0x7f7f7f7f;
int t;
ll n, ans;
void dfs(ll m, ll x) {
if (x / 10 > n) {
//取余的数都大于n直接返回
return;
}
if (m * m % x == n) {
ans = min(m, ans);//找出最小的答案
return;
}
for (int i = 0; i <= 9; i++) {
ll a = i * x + m;
ll t = x * 10;
if (a * a % t == n % t) { //保证已知后缀相同才往下搜索
dfs(a, x * 10);
}
}
}
int main() {
scanf("%d", &t);
while (t--) {
scanf("%lld", &n);
if (n % 10 == 2 || n % 10 == 3 || n % 10 == 7 || n % 10 == 8) {
printf("None\n"); //没有数的平方个位上是这些数
} else {
ans = INF;
dfs(0, 1);
if (ans != INF) {
printf("%lld\n", ans);
} else {
printf("None\n");
}
}
}
return 0;
}