SPOJ ONEZERO(搜索)
搜索的好题,,,,
摘自题解:
题意;
给一个数n,求n 的最小的倍数,满足它的10进制 表示中每一位不是0就是1。
思路:
用f(x)表示被n整除取模后的最小数,那么从0开始,每次往后添0或者1,如果得到的数与某个已经得到的数同余,就扔掉,不然就加入队列中继续搜。。。
时间复杂度O(N).
代码如下:
#include <cstdio> #include <cstring> #include <string> #include <queue> #include <algorithm> using namespace std; #define M 20005 struct Node{ int m; bool flag; }; bool vis[M]; Node a[M]; int ok(int x) { int t; while(x) { t = x%10; x/=10; if(t!=0&&t!=1) return 0; } return 1; } void print(int x) { if(x<0) return; print(a[x].m); printf("%d", a[x].flag); if(x==0) printf("\n"); } int main () { int t, n; scanf("%d",&t); while(t--) { scanf("%d",&n); memset(vis,0,sizeof(vis)); if(ok(n)) printf("%d\n", n); else { queue<int>q; int tt1, tt2; vis[1] = 1; a[1].m = -1; a[1].flag = 1; q.push(1); while(!q.empty()) { tt1 = q.front(); q.pop(); if(vis[(tt1*10)%n]==0) { tt2 = tt1*10%n; a[tt2].m = tt1; a[tt2].flag = 0; if(tt2==0) break; vis[tt2] = 1; q.push(tt2); } if(vis[(tt1*10+1)%n]==0) { tt2 = (tt1*10+1)%n; a[tt2].m = tt1; a[tt2].flag = 1; if(tt2==0) break; vis[tt2] = 1; q.push(tt2); } } print(0); } } return 0; }