HDU4294 Multiple
去年省赛教练会汝哥讲过一个结论,至多两个数字就可以拼出任何数的倍数。
证明可以这样,AAAA...AAA若干个A,模X,能得到的余数种类是有限的,至多是1~X-1,那么总会有n个A和m个A这两个数模X余数相等,他们相减就得到了X的倍数,而相减得到的数就是两个数组成的。
这样就可以对一个数先枚举一下,对两个数再枚举一下,找组成的那个数,可以BFS。一个数用来拼数字的时候超过一定长度就可以停下了,一步步模会出现循环。
枚举得到的答案比较一下更新,最后输出。
比赛时候思维乱,代码不太工整,见谅。
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<queue> 5 using namespace std; 6 const int maxn = 51111; 7 int n, m, c; 8 int pace[maxn], record[maxn], res[maxn]; 9 char ans[maxn], re[maxn]; 10 int num[5]; 11 int comp(const void *a, const void *b) 12 {return *(int*)a - *(int*)b;} 13 bool BFS() 14 { 15 queue<int> q; 16 int i, lin, nex; 17 for(i = 0; i < m; ++ i) 18 { 19 if(!num[i] || pace[num[i] % n]) continue; 20 pace[num[i] % n] = 1; 21 record[num[i] % n] = -1; 22 res[num[i] % n] = num[i]; 23 q.push(num[i] % n); 24 } 25 while(!q.empty()) 26 { 27 lin = q.front(), q.pop(); 28 if(pace[lin] > maxn) return false; 29 if(!lin) return true; 30 for(i = 0; i < m; ++ i) 31 { 32 nex = (lin * c + num[i]) % n; 33 if(!pace[nex]) 34 { 35 res[nex] = num[i]; 36 record[nex] = lin; 37 pace[nex] = pace[lin] + 1; 38 q.push(nex); 39 } 40 } 41 } 42 return false; 43 } 44 int al, rl; 45 void Prin(int i) 46 { 47 if(record[i] != -1) Prin(record[i]); 48 re[rl ++] = res[i] + '0'; 49 } 50 bool cmp(int &al, int &rl) 51 { 52 if(al > rl) return true; 53 if(al < rl) return false; 54 for(int i = 0; i < al; ++ i) 55 { 56 if(ans[i] > re[i]) return true; 57 if(ans[i] < re[i]) return false; 58 } 59 return false; 60 } 61 int main() 62 { 63 int i, j; 64 bool flag; 65 while(scanf("%d%d", &n, &c) != EOF) 66 { 67 flag = 0; 68 al = maxn - 1; 69 for(i = 1; i < c; ++ i) 70 { 71 num[0] = i, m = 1; 72 memset(pace, 0, sizeof(pace)); 73 if(BFS()) 74 { 75 flag = true; 76 rl = 0; 77 Prin(0); 78 if(cmp(al, rl)) al = rl, memcpy(ans, re, sizeof(ans)); 79 } 80 } 81 if(!flag) 82 { 83 for(i = 1; i < c; ++ i) 84 for(j = 0; j < i; ++ j) 85 { 86 num[0] = j, num[1] = i, m = 2; 87 memset(pace, 0, sizeof(pace)); 88 if(BFS()) 89 { 90 rl = 0; 91 Prin(0); 92 if(cmp(al, rl)) al = rl, memcpy(ans, re, sizeof(ans)); 93 } 94 } 95 } 96 for(i = 0; i < al; ++ i) putchar(ans[i]); 97 printf("\n"); 98 } 99 return 0; 100 }