超级密码
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2927 Accepted Submission(s): 939
Problem Description
Ignatius花了一个星期的时间终于找到了传说中的宝藏,宝藏被放在一个房间里,房间的门用密码锁起来了,在门旁边的墙上有一些关于密码的提示信息: 密码是一个C进制的数,并且只能由给定的M个数字构成,同时密码是一个给定十进制整数N(0<=N<=5000)的正整数倍(如果存在多个满足条件的数,那么最小的那个就是密码),如果这样的密码存在,那么当你输入它以后门将打开,如果不存在这样的密码......那就把门炸了吧.
注意:由于宝藏的历史久远,当时的系统最多只能保存500位密码.因此如果得到的密码长度大于500也不能用来开启房门,这种情况也被认为密码不存在.
注意:由于宝藏的历史久远,当时的系统最多只能保存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.我保证输入数据都是合法的.
注意:在给出的M个数字中,如果存在超过10的数,我们约定用A来表示10,B来表示11,C来表示12,D来表示13,E来表示14,F来表示15.我保证输入数据都是合法的.
Output
对于每组测试数据,如果存在要求的密码,则输出该密码,如果密码不存在,则输出"give me the bomb please".
注意:构成密码的数字不一定全部都要用上;密码有可能非常长,不要试图用一个整型变量来保存密码;我保证密码最高位不为0(除非密码本身就是0).
注意:构成密码的数字不一定全部都要用上;密码有可能非常长,不要试图用一个整型变量来保存密码;我保证密码最高位不为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
Huge input, scanf is recommended.
Hint
HintAuthor
Ignatius.L
Source
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<queue> 5 int T , mod , c , n ; 6 char a[500 + 10] ; 7 bool vis[5100 + 10] ; 8 int num[20] ; 9 struct node 10 { 11 int step , ret ; 12 node () {} 13 node (int step , int ret) : step (step) , ret (ret) {} 14 }; 15 struct link 16 { 17 int v , nxt ; 18 }e[200000 + 10]; 19 void echo (int an) 20 { 21 int k = 0 ; 22 for (int i = an ; ~ i ; i = e[i].nxt) { 23 if (e[i].v < 10) a[k ++] = '0' + e[i].v ; 24 else if (e[i].v >= 10) a[k ++] = e[i].v - 10 + 'A' ; 25 } 26 // printf (" k=%d " , k) ; 27 for (int i = k - 1 ; i >= 0 ; i --) { 28 printf ("%c" , a[i]) ; 29 } 30 printf (" ") ; 31 } 32 33 bool bfs () 34 { 35 int E = -1 ; 36 std::queue<node> q ; 37 while (!q.empty ()) q.pop () ; 38 memset (vis , 0 , sizeof(vis)) ; 39 node ans , tmp ; 40 int cnt = E + 1 ; 41 for (int i = 0 ; i < n ; i ++) { 42 if (num[i] != 0 && !vis[num[i]%mod]) { 43 ans = node (1 , num[i]%mod) ; 44 e[cnt].v = num[i] ; e[cnt].nxt = E ; cnt ++ ; 45 vis[num[i]%mod] ; 46 if (num[i]%mod == 0) {echo (cnt - 1) ; return true ;} 47 q.push (ans) ; 48 } 49 } 50 // for (int i = 0 ; i < n ; i++) printf ("%d " , num[i]) ; printf (" ") ; 51 while (!q.empty ()) { 52 ans = q.front () ; q.pop () ; 53 E ++ ; 54 // printf ("step=%d , ret=%d " , ans.step , ans.ret) ; 55 for (int i = 0 ; i < n ; i++) { 56 tmp.ret = (ans.ret * c + num[i]) % mod ; 57 tmp.step = ans.step + 1 ; 58 // printf ("+%d=(%d) " , num[i],tmp.ret) ; 59 if (tmp.step > 500) continue ; 60 if (vis[tmp.ret]) continue ; 61 e[cnt].v = num[i] ; e[cnt].nxt = E ; cnt ++ ; 62 // printf ("(%d)ans.ret=%d " , num[i] , ans.ret) ; 63 if (tmp.ret == 0) {echo (cnt - 1) ; return true ;} 64 vis[tmp.ret] = 1 ; 65 q.push (tmp) ; 66 } 67 } 68 return false ; 69 } 70 71 int main () 72 { 73 //freopen ("a.txt" , "r" , stdin ) ; 74 scanf ("%d" , &T) ; 75 while (T--) { 76 scanf ("%d%d%d" , &mod , &c , &n) ; 77 // printf ("mod=%d,c=%d,n=%d " , mod , c , n ) ; 78 // printf ("hehe :%s " , a ) ; 79 for (int i = 0; i < n; i++){ 80 scanf("%s", a); 81 if (a[0] <= '9' && a[0] >= '0') num[i] = a[0] - '0'; 82 else if (a[0] <= 'F' && a[0] >= 'A') num[i] = a[0] - 'A' + 10; 83 } 84 std::sort (num , num + n) ; 85 if (mod == 0) { 86 if (num[0] == 0) puts ("0") ; 87 else puts ("give me the bomb please") ; 88 continue ; 89 } 90 if ( !bfs () ) puts ("give me the bomb please") ; 91 } 92 return 0 ; 93 }
bfs能用来生成数,给赞啊。规避了大数的做法也很6.