题目连接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=242&problem=3160&mosmsg=Submission+received+with+ID+8870784
思路:
(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; }