思路:
(1):从i-1的答案为往后推出i为的答案(每次在i-1的答案前面加上0-9,判断是否满足条件)
(2):在模拟的时候要注意,不能在某个i-1为的答案枚举0-9时每次都用O(n^2)的复杂度去做大数乘法,这样会TLE
要将枚举时复杂度降低为O(n)才能过。
(3):输出时要去掉做高位为零的数(N==1是特判)
CODE:
/*AC代码:420ms*/
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#define MAXN 505
using namespace std;
struct Node
{
char num[505];
};
int N,cas;
vector<Node>V[MAXN];
int ans[1200],w[1200];
int cmp(const void *p1,const void *p2)
{
return strcmp(((struct Node *)p1)->num,((struct Node *)p2)->num);
}
void Judge(Node v,int n)
{
int i,j;
memset(ans,0,sizeof(ans));
for(i=n-1;i>=0;i--)
{
for(j=n-1;j>=0;j--)
ans[i+j+2]+=(v.num[i]-'0')*(v.num[j]-'0');
}
}
void Init()
{
int i,j,k,m,l;
Node temp,u,v;
strcpy(temp.num,"0");V[1].push_back(temp);
strcpy(temp.num,"1");V[1].push_back(temp);
strcpy(temp.num,"5");V[1].push_back(temp);
strcpy(temp.num,"6");V[1].push_back(temp);
for(i=2;i<=500;i++)
{
int size=V[i-1].size();
for(j=0;j<size;j++)
{
u=V[i-1][j];
Judge(u,i-1);
for(k=0;k<=9;k++)
{
for(m=0;m<=2*i;m++)
w[m]=ans[m];
w[0]+=k*k;
for(m=0;m<i-1;m++)
w[m+1]+=2*k*(u.num[m]-'0');
bool ok=true;
for(m=2*i-2,l=i-1;m>=i;m--,l--)
{
w[m-1]+=w[m]/10;
w[m]%=10;
if(w[m]!=u.num[l-1]-'0')
{ok=false;break;}
}
w[m]%=10;
if(k!=w[m]) ok=false;
if(ok)
{
v.num[0]=k+'0';
strcpy(v.num+1,u.num);
V[i].push_back(v);
}
}
}
qsort(&V[i][0],V[i].size(),sizeof(V[i][0]),cmp);
}
}
int main()
{
int T,i;
Init();
cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
printf("Case #%d:",cas++);
int size=V[N].size();
if(!size)
printf(" Impossible\n");
else
{
for(i=0;i<size;i++)
{
if(V[N][i].num[0]!='0'||N==1)
printf(" %s",V[N][i].num);
}
printf("\n");
}
}
return 0;
}