超级密码(dfs)

超级密码233

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3406    Accepted Submission(s): 1080


Problem Description
Ignatius花了一个星期的时间终于找到了传说中的宝藏,宝藏被放在一个房间里,房间的门用密码锁起来了,在门旁边的墙上有一些关于密码的提示信息:
密码是一个C进制的数,并且只能由给定的M个数字构成,同时密码是一个给定十进制整数N(0<=N<=5000)的正整数倍(如果存在多个满足条件的数,那么最小的那个就是密码),如果这样的密码存在,那么当你输入它以后门将打开,如果不存在这样的密码......那就把门炸了吧.

注意:由于宝藏的历史久远,当时的系统最多只能保存500位密码.因此如果得到的密码长度大于500也不能用来开启房门,这种情况也被认为密码不存在.
 
Input
输入数据的第一行是一个整数T(1<=T<=300),表示测试数据的数量.每组测试数据的第一行是两个整数N(0<=N<=5000)和C(2<=C<=16),其中N表示的是题目描述中的给定十进制整数,C是密码的进制数.测试数据的第二行是一个整数M(1<=M<=16),它表示构成密码的数字的数量,然后是M个数字用来表示构成密码的数字.两个测试数据之间会有一个空行隔开.

注意:在给出的M个数字中,如果存在超过10的数,我们约定用A来表示10,B来表示11,C来表示12,D来表示13,E来表示14,F来表示15.我保证输入数据都是合法的.
 
Output
对于每组测试数据,如果存在要求的密码,则输出该密码,如果密码不存在,则输出"give me the bomb please".

注意:构成密码的数字不一定全部都要用上;密码有可能非常长,不要试图用一个整型变量来保存密码;我保证密码最高位不为0(除非密码本身就是0).
 
Sample Input
3 22 10 3 7 0 1 2 10 1 1 25 16 3 A B C
 
Sample Output
110 give me the bomb please CCB
Hint
Hint
Huge input, scanf is recommended.

r= k (mod c)則 (k*p+a)(mod c)=(r*p+a)(mod c)

如果某个数值序列的余数为r.....如果某个余数已经被构造过...那么后面得到的一定是与原来构造过的余数序列相同的序列 而由BFS的性质.最短的一定是最先被构造出来的..所以.....先到先得!(每一位使用什么数字都是不变的哦.....就是在同一个数值集合内...).  如果看不懂 看下面的

例如 如果 k1%c==k1k2%c   则 k1k3%c==k1k2k3%c

再特殊一点的 比如 3%4==3    27%4==3  则 31%4==271%4 ,32%4==272%4  ,33%4==273%4...............

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<queue>
  4 using namespace std;
  5 bool  xx[20];
  6 int m,n,x;
  7 struct haha
  8 {
  9     int len;
 10     int num[555];
 11 }q,temp;
 12 bool vis[5555];
 13 int judge(struct haha &p)//计算其除以n的余数
 14 {
 15     int len=p.len,tmp=0;
 16     for(int i=1;i<=len;i++)
 17     {
 18         tmp=(tmp*x+p.num[i])%n;
 19     }
 20     return tmp;
 21 }
 22 void print(struct haha &p)//找到后输出
 23 {
 24     for(int i=1;i<=q.len;i++)
 25     {
 26         printf("%X",q.num[i]);//输出大写的用X        
 27     }
 28     printf("
");
 29     return ;
 30 }
 31 void  BFS()
 32 {
 33     int i;
 34     memset(vis,0,sizeof(vis));
 35     queue<struct haha>que;
 36     for(i=1;i<16;i++)
 37     {
 38         if(xx[i]==true)
 39         {
 40             q.len=1;
 41             q.num[1]=i;
 42             int  k=judge(q);
 43             if(k==0)
 44             {
 45                 print(q);
 46                 return ;
 47             }
 48             else vis[k]=1;
 49             que.push(q);
 50         }
 51     }
 52     while(!que.empty())
 53     {
 54         temp=que.front();
 55         que.pop();
 56         for(i=0;i<16;i++)
 57         {
 58             if(xx[i]==false) continue;
 59             q=temp;
 60             q.len+=1;
 61             q.num[q.len]=i;
 62             int k=judge(q);
 63             if(k!=0)
 64             {
 65                 if(!vis[k]&&q.len<=500)
 66                 {
 67                     vis[k]=true;
 68                     que.push(q);
 69                 }
 70             }
 71             else
 72             {
 73                 print(q);
 74                 return ;
 75             }
 76             
 77         }
 78     }
 79     printf("give me the bomb please
");
 80 }
 81 int main()
 82 {
 83     int cas,i;
 84     scanf("%d",&cas);
 85     while(cas--)
 86     {
 87         memset(xx,0,sizeof(xx));
 88         scanf("%d %d %d",&n,&x,&m);
 89         for(i=0;i<m;i++)
 90         {
 91             int k;
 92             scanf("%x",&k);//用%x输入 省去了转化为数字的繁琐
 93             xx[k]=1;
 94         }
 95         if(n==0)
 96         {
 97             if(xx[0]==true)
 98                 printf("0
");
 99             else printf("give me the bomb please
");
100             continue;
101         }
102         BFS();
103         
104     }
105     return 0;
106 }
原文地址:https://www.cnblogs.com/a1225234/p/5017083.html