hdu1664 bfs+余数判重

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("\n");
 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\n",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\n",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("\n");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\n",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\n",(double)clock()/CLOCKS_PER_SEC);
140     return 0;
141 }
View Code

 

posted @ 2015-12-22 15:26  cdongyang  阅读(219)  评论(0编辑  收藏  举报