密码宝盒
时间限制:2000 ms | 内存限制:65535 KB
难度:3
描述
小M得到了一个宝盒,可惜打开这个宝盒需要一组神奇的密码,然而在宝盒的下面
有关于密码的提示信息:密码是一个C进制的数,并且只能由给定的M个数字中的某些构成,密码不超过500位,同时密码是一个给定十进制整数N的正整数倍,
如果这样的密码存在,那么你就可以打开宝盒并得到宝贝,如果不存在
这样的密码......那你就只能收藏这个宝盒了.
输入
输入一个T,表示有T组测试数据,(T≤500)
接下来输入N,C,M(N,C,M如上所述)( 0≤N≤5000, 1≤M≤16 , 2≤C≤16 )
然后M个数,表示密码中含有哪些数字。(输入保证合法)
用A来表示10, B来表示11, C来表示12 , D来表示13, E来表示14, F来表示15
输出
输出:密码如果存在,输入最小的那个为密码,不存在”So Sorry.”(密码不含前导零)
样例输入
3
22 10 3
7 0 1
2 10 1
1
25 16 3
A B C
样例输出
110
So Sorry.
CCB
#include <queue> #include <string> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N = 5005; bool vis[N]; string ans; int a[17],pre[N],ansAt[N],n,m,c; int ctoi(char c) { return c >= '0' && c <= '9' ? c - '0' : c - 'A' + 10; } char itoc(int i) { return i <= 9 ? i + '0' : i + 'A' - 10; } bool bfs() { queue<int> q; q.push(0); while(!q.empty()) { int cur = q.front();q.pop(); for(int i=0;i<m;i++) { int nxt = (cur * c + a[i]) % n; if(cur == 0 && a[i] == 0 || vis[nxt]) continue; vis[nxt] = true; ansAt[nxt] = a[i]; pre[nxt] = cur; if(nxt == 0) return true; q.push(nxt); } } return false; } bool check() { ans = ""; int p = 0; do { ans += itoc(ansAt[p]); p = pre[p]; }while(p); return (int)ans.size() <= 500; } int main() { int T; scanf("%d",&T); while(T--) { memset(vis,false,sizeof(vis)); scanf("%d%d%d",&n,&c,&m); for(int i=0;i<m;i++) { char num[3]; scanf("%s",num); //以免存入空格 a[i] = ctoi(num[0]); } sort(a,a+m); if(n == 0) { puts(a[0] == 0 ? "0" : "So Sorry."); continue; } if(bfs() && check()) { for(int i=(int)ans.size()-1;i>=0;i--) putchar(ans[i]); puts(""); } else puts("So Sorry."); } return 0; }