Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1827 Accepted Submission(s): 714
思路: 广搜,首先证明出N位后缀只与M的后N位有关。比如三位数100a+10b+c平方后展开为 10000a^2+2000ab+100b^2+200ac+20bc+c^2很显然,平方后的最后一位只与c有关,最后两位只与bc有关,最后三位abc都有关,可见可以一位一位的判断。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
__int64 n;
struct node
{
int num; //判断到第几位
__int64 w; //当前判断的数字
};
node node1,node2;
bool operator<(node n1,node n2) //优先队列,必须输出最小的数
{
return n1.w>n2.w; //从小到大
}
void bfs()
{
priority_queue <node> q;
__int64 t;
while(!q.empty())
q.pop();
node1.num=0;
node1.w=0;
q.push(node1);
while(!q.empty())
{
node1=q.top();//优先队列用q.top(),队列用q.front()
q.pop();
t=(__int64)pow(10.0,node1.num);
if(node1.w*node1.w%t==n)
{
printf("%I64d\n",node1.w);
return ;
}
for(int i=0;i<10;i++)
{
node2.num=node1.num+1;//向右增加一位
node2.w=node1.w+t*i; //得到增加一位的数字
if(node2.w*node2.w%(t*10)==n%(10*t))
q.push(node2);
}
}
printf("None\n");
}
int main()
{
int m;
scanf("%d",&m);
while(m--)
{
scanf("%I64d",&n);
if(n%10==2||n%10==3||n%10==7||n%10==8)
printf("None\n");
else
bfs();
}
}
hdu4394Digital Square(优先队列+广搜+__int64)
原文:http://www.cnblogs.com/dshn/p/4887807.html