input
n 不超过50个例子,n==0结束输入
Sample Input
7 15 16 101 0
output
最少个不同数字的n的倍数的x,若不同数字个数一样,输出最小的x
Sample Output
7 555 16 1111
根据数论里面的知识点:
对于任意的整数 n ,必然存在一个由不多于两个的数来组成的一个倍数。 因为 a ,aa , aaa…… 取 n+1 个,则由鸽笼原理,必有两个模 n 余数相同,相减即得 n 的倍数 m 。而 m 只由 a 、 0 组成。
1 #include <bits/stdc++.h> 2 #include <cstdio> 3 #include <queue> 4 #include <cstring> 5 #include <iostream> 6 #include <cstdlib> 7 #include <algorithm> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <ctime> 12 #include <cmath> 13 #include <cctype> 14 #include <string> 15 #include <bitset> 16 #define MAX 65600 17 #define LL long long 18 #define uint unsigned short 19 using namespace std; 20 int cas=1,T,n; 21 struct node1 22 { 23 int i,r; 24 }; 25 char v1[MAX][10]; 26 int bfs1() 27 { 28 int step=1,d=0; 29 queue<node1>q[2]; 30 memset(v1,0,sizeof(v1[0])*n); 31 for(int i=1;i<10;i++) { q[0].push((node1){i,i%n});v1[i%n][i]=1; } 32 while(!q[d].empty()) //两个队列bfs,一个队列存一步里面走的 33 { 34 while(!q[d].empty()) 35 { 36 node1 u=q[d].front();q[d].pop(); 37 if(u.r==0) 38 { 39 for(int i=0;i<step;i++) printf("%d",u.i); 40 printf(" "); 41 return 1; 42 } 43 node1 v; 44 v.r=(u.r*10+u.i)%n; 45 if(v1[v.r][u.i]) continue; 46 v.i=u.i;q[d^1].push(v); 47 v1[v.r][u.i]=1; 48 } 49 step++; 50 d^=1; 51 } 52 return 0; 53 } 54 struct node 55 { 56 uint r,i,a,b; //a,b是两个不同的数字且a<b<10,r是余数,i是当前取的数,输出时要用 57 int fa; //父结点,查找路径用 58 }; 59 node q[MAX*45]; 60 char v[MAX][45]; 61 uint idx(uint &a,uint&b) { return (b*b-b)/2+a; } 62 void init(int &end) //初始化队列,一次将所有的入队用的内存太多,也可以分成45次bfs() 63 { 64 for(int i=10;i<100;i++) //从小到大入队 65 { 66 int a=i/10,b=i%10; //a是个位,b是十位 67 if(a==b)//a,b相同时可以是550 551 552 553 554 556 557 558 559 68 { 69 for(int j=0;j<10;j++) 70 { 71 if(a==j) continue; 72 node&u=q[end]; 73 u.i=i;u.r=i%n; 74 u.a=min(a,j);u.b=max(a,j);u.fa=-1; 75 int id=idx(u.a,u.b); 76 v[a][id]=v[i][id]=1; 77 end++; 78 // printf("%d %d %d %d %d ",u.i,u.r,u.a,u.b,u.fa); 79 } 80 continue; 81 } 82 node&u=q[end]; //a,b不同时直接入队即可 83 u.i=i;u.r=i%n; 84 u.a=min(a,b);u.b=max(a,b);u.fa=-1; 85 int id=idx(u.a,u.b); 86 v[a][id]=v[i][id]=1; 87 end++; 88 // printf("%d %d %d %d %d ",u.i,u.r,u.a,u.b,u.fa); 89 } 90 } 91 void print(int u) 92 { 93 if(q[u].fa==-1) { printf("%d",q[u].i);return; } 94 print(q[u].fa); 95 printf("%d",q[u].i); 96 } 97 void bfs2() 98 { 99 memset(v,0,sizeof(v[0])*n); 100 int front=0,end=0; 101 init(end); 102 while(front<end) 103 { 104 node&u=q[end],&f=q[front]; 105 int id=idx(f.a,f.b); 106 if(f.r==0) { print(front);printf(" ");return; } 107 u.r=((int)f.r*10+f.a)%n; 108 if(!v[u.r][id]) //加一位a 109 { 110 v[u.r][id]=1; //刚开始错在这,没有标记,也是够傻了。。。而且还一直找不到。。。 111 u.a=f.a;u.b=f.b;u.fa=front; 112 u.i=f.a; 113 end++; 114 } 115 node&p=q[end]; 116 p.r=((int)f.r*10+f.b)%n; 117 if(!v[p.r][id]) //加一位b 118 { 119 v[p.r][id]==1; 120 p.a=f.a;p.b=f.b;p.fa=front; 121 p.i=f.b; 122 end++; 123 } 124 front++; 125 // printf("%d %d ",front,end); 126 } 127 } 128 int main() 129 { 130 //freopen("out","w",stdout); 131 //freopen("in","r",stdin); 132 //scanf("%d",&T); 133 while(scanf("%d",&n)==1&&n) 134 //for(n=65535;n>0;n--) 135 { 136 if(bfs1()) continue; 137 bfs2(); 138 } 139 //printf("time=%.3lf ",(double)clock()/CLOCKS_PER_SEC); 140 return 0; 141 }