转载请注明出处,谢谢http://blog.youkuaiyun.com/ACM_cxlove?viewmode=contents by---cxlove
题目:给出n,求出最小的m,满足m^2 % 10^k = n,其中k=0,1,2
http://acm.hdu.edu.cn/showproblem.php?pid=4394
只要有一个x满足条件便行了
我们可以初步发现,某个数个位确定,那么平方的最后一位肯定是确定的,那么如果后两们确定,那么平方的最后两们也是确定的,这可以通过乘法的规律得到
那我们只需要BFS一下,不断地找满足最后指定位数的数,1位,2位,……直到找到第一个满足条件的。
注意这里可能是100001这种情况
所以记录当前数字大小,当前位置,可能暂时的高位为0,以后下一个添加的数为多少
#include<iostream>
#include<cstdio>
#include <queue>
#include<cstring>
#include<algorithm>
#include<vector>
#define pb(a) push_back(a)
#define MOD 1000000007
#define LL long long
using namespace std;
struct Node
{
LL now;
int len,next;
Node(){}
Node(LL _n,int _l,int _ne):now(_n),len(_l),next(_ne){}
bool operator<(const Node n1)const
{
return now>n1.now;
}
}u,v;
int t;
LL n;
LL fac[18];
void bfs()
{
int L=0;
LL tmp=n;
while(tmp)
{
L++;
tmp/=10;
}
priority_queue<Node>que;
que.push(Node(0,0,0));
while(!que.empty())
{
u=que.top();
// cout<<u.now<<" "<<u.len<<" "<<u.next<<endl;
que.pop();
if(u.len==L) {printf("%I64d\n",u.now);return ;} //已经和n的位数相同,说明已经找到
if(u.next!=9){que.push(Node(u.now,u.len,u.next+1));} //如果为9,说明已经遍历了0-9,不再加入队列
v=u;
v.len++; //长度加1
v.now=v.now+fac[v.len-1]*u.next; //在最高位加上这个数
v.next=0; //下一次又从0开始
// cout<<v.now<<" "<<v.len<<" "<<v.next<<endl;
if((v.now*v.now)%fac[v.len]==n%fac[v.len]) que.push(v);
}
printf("None\n");
}
int main()
{
scanf("%d",&t);
fac[0]=1;
for(int i=1;i<18;i++) fac[i]=fac[i-1]*10;
while(t--)
{
scanf("%I64d",&n);
bfs();
}
return 0;
}