http://poj.org/problem?id=1426
(1)用了结构体加上优先队列:
struct node { int n, v, digit; node *pre; }
注意到深度为100,内存不足。。(字典树深度为10,深度没有这么大)。
(2)从小到大枚举01序列,超时。
(3)深搜,将部分的0替换成1,可以认为是一种技巧性的枚举,AC。
具体代码:


#include<stdio.h> #include<string.h> int m, flag; int re[120]; int yes() { int i, c=0; for(i=1;i<=100;i++) { c*=10; c+=re[i]; c%=m; } if(c) return 0; return 1; } void put() { int i; for(i=1;i<=100;i++) printf("%d", re[i]); printf("\n"); } void dfs(int x) { int i; if(flag) return ; if(yes()) {put(); flag=1; return ;} for(i=x;i<=100;i++) { if(re[i]) continue; re[i]=1; dfs(i+1); if(flag) return ; re[i]=0; } } int main() { while(scanf("%d", &m)!=EOF, m) { memset(re, 0, sizeof(re)); re[1]=1; flag=0; dfs(2); } return 0; }
这里附上两种错误的代码,予以警示。
1)超内存代码:


#include<stdio.h> #include<string.h> int m; struct node { int n, v, digit; node *pre; }q[1000000], e, s; int tot, re[200]; int bfs() { int i, j, k; int start, tail; start=tail=0; e.n=1, e.v=1, e.digit=1, e.pre=NULL; q[tail]=e; while(start<=tail) { e=q[start++]; if(e.n==0) break; for(i=0;i<2;i++) { s.n=e.n*10+i; s.n%=m; s.v=i; s.digit=e.digit+1; s.pre=&q[start-1]; q[++tail]=s; } } tot=0; while(e.pre!=NULL) { re[tot++]=e.pre->v; e.pre=e.pre->pre; } for(i=tot-1;i>=0;i--) printf("%d", re[i]); printf("%d\n", e.v); } int main() { while(scanf("%d", &m)!=EOF, m) { bfs(); } }
2)超时代码:


#include<stdio.h> #include<string.h> int m, a[120]; int yes() { int i, s=0; for(i=100;i>=1;i--) { s*=10; s+=a[i]; s%=m; } if(s) return 0; else return 1; } int main() { int i, j; while(scanf("%d", &m)!=EOF, m) { memset(a, 0, sizeof(a)); a[1]=1; while(1) { for(i=1;i<=100;i++) if(!a[i]) { a[i]=1; for(j=1;j<i;j++) a[j]=0; break; } if(yes()) break; } for(i=100;i>=1;i--) if(a[i]) break; for(;i>=1;i--) printf("%d", a[i]); printf("\n"); } return 0; }