注解
1、BFS,广度优先搜索。因为某个数的平方的末位只跟该数的最后1位有关系,末两位只跟该数的最后两位有关系,依次类推。所以应该从最后一位开始暴力往前搜索,满足条件的就加入队列,每次往前搜1位,也就是乘10再加上当前的数字,成为新数字,再试这个新数字是否满足题目要求。
2、用优先队列,而不是普通队列。因为本题要求输出最小的值,因此,值越小,优先级越高。用STL中的priority_queue,优先队列更合适。要设置优先队列的优先级,用friend友元函数重载<运算符。
代码
#include <iostream>
#include <queue>
#include <cmath>
using namespace std;
typedef long long int LL;
int n;
struct Node {
LL num;
int base;
friend bool operator < (Node n1, Node n2) {
return n1.num>n2.num; //节点的数字越大,优先级越小(题目要求输出最小的数字)
}
};
int digit(int m) {
int re = 0;
while(m) {
re++;
m /= 10;
}
return re;
}
void bfs(int n) {
priority_queue<Node> q;
for(int i=0; i<10; i++) {
if((i*i)%10==n%10) {
Node node = {i, 10};
q.push(node); //找到可能的末位数字加入队列
}
}
while(q.size()>0) {
Node top = q.top();
q.pop();
LL tmp = (top.num*top.num)%(LL)pow(10, digit(n));
if(tmp==n) {
cout<<top.num<<endl;
return;
}
for(int i=0; i<10; i++) {
Node nodetmp = {i*top.base+top.num, top.base*10};
if((nodetmp.num*nodetmp.num)%nodetmp.base==n%nodetmp.base) {
q.push(nodetmp); //如果后log10(base)位相同(base=10,后1位,base=100,后2位)那么把该数字加入队列
}
}
}
cout<<"None"<<endl;
return;
}
int main() {
int T;
cin>>T;
for(int i=0; i<T; i++) {
cin>>n;
bfs(n);
}
return 0;
}