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 }
posted @ 2012-09-16 19:25  CSGrandeur  阅读(1392)  评论(2编辑  收藏  举报