题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4394
题目意思:
给定一个N(0<=N<=10^9),求最小的M,使得M^2%10^x=N ( x=0,1,2,3... ).
解题思路:
搜索。
从低位往高位依次处理。
abcde
* abcde
------------
N(...n3n2n1)
显然可以根据N的个位确定e的可能的情况,把e确定后,再根据2*d*e=n2,得出d的可能情况,再根据2*c*e+d*d=n3得出c的可能情况,依次往高位搜索,最后比较求出最小的即可。
代码:
//#include<CSpreadSheet.h>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
vector<int>myv[12]; //myv[i]平方的个位为i的数字集合
int n;
bool flag;
int ans[22],cnt;
int last[22];
vector<int>be[12][12];//be[i][j]表示乘积个位为i,一个乘数为j,另外一个乘数的集合
void init()
{
myv[1].push_back(1);myv[1].push_back(9);
myv[4].push_back(2),myv[4].push_back(8);
myv[6].push_back(4),myv[6].push_back(6);
myv[9].push_back(3),myv[9].push_back(7);
myv[5].push_back(5);
myv[0].push_back(0);
for(int i=0;i<=9;i++) //预处理出所有的情况
for(int j=0;j<=9;j++)
{
for(int k=0;k<=9;k++)
{
if(j*k%10==i)
be[i][j].push_back(k);
}
}
}
void dfs(int cur,int ji,int num) //cur表示当前的数,ji表示从低位进位的量,num表示第几位(从低位开始计算)
{
if(!cur) //结束了
{
cnt=num-1;
if(flag)
{
bool iste=false;
for(int i=num-1;i>=1;i--) //能否更新小点
{
if(ans[i]<last[i])
{
iste=true;
break;
}
else if(ans[i]>last[i])
break;
}
if(iste)
memcpy(last,ans,sizeof(ans));
}
else
memcpy(last,ans,sizeof(ans));
flag=true;
return ;
}
int temp=ji,le,pos=cur%10;
for(int i=2;i<num;i++) //计算该位的值
{
temp+=ans[i]*ans[num+1-i];
}
le=temp%10;
if(pos<le)
pos+=10;
pos-=le;
if(pos%2)
{
return ;
}
for(int j=0;j<be[pos][2].size();j++)
{
int pp=be[pos][2][j];
for(int i=0;i<be[pp][ans[1]].size();i++)
{
ans[num]=be[pp][ans[1]][i];
int tt=temp;
tt+=ans[num]*ans[1]*2;
dfs(cur/10,tt/10,num+1);
// printf("cur:%d \n",cur);
//system("pause");
/*if(flag)
return;*/
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
/*freopen("out.txt","w",stdout);
for(int i=1;i<=40;i++)
printf("%d ",i*i);*/
int t;
init();
scanf("%d",&t);
while(t--)
{
flag=false;
scanf("%d",&n);
cnt=0;
for(int i=0;i<myv[n%10].size();i++)
{
ans[1]=myv[n%10][i];
dfs(n/10,ans[1]*ans[1]/10,2);
/*if(flag)
break;*/
}
if(flag)
{
int i=cnt;
while(!last[i]&&i>1)
i--;
for(;i>=1;i--)
{
printf("%d",last[i]);
}
putchar('\n');
}
else
printf("None\n");
}
return 0;
}