密码宝盒
时间限制: 2 Sec 内存限制: 64 MB题目描述
小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<stdio.h> # include<string.h> # include<algorithm> # include<queue> using namespace std; int n,c,m,b[5001],a[17],v[5001],mm[5001],k1; char c1[5001]; int charge1(char c) { if(c>='0'&&c<='9') return c-'0'; else return c-'A'+10; } char charge2(int c) { char a; if(c<=9) { return c+'0'; } else { return c-10+'A'; } } int dfs(){ int q; queue<int>s; s.push(0); while(!s.empty()) { q=s.front(); s.pop(); for(int i=0;i<m;i++) { int k=(q*c+a[i])%n;//看是否是c的整数倍 if(!v[k]&&(q||a[i]))//未标记,并且q和a[i]不能同时为0, { //否则开始k一定为0,对结果有影响 v[k]=1;//标记,不在重复查找 b[k]=a[i]; mm[k]=q; //写几个数体会一下它的用处 s.push(k); if(k==0) return 1; } } } return 0; } int visit (){ //判断密码是否超过500位 并且 找出密码 int i=0; int k=mm[0]; c1[i++]=charge2(b[0]); while(k) { c1[i++]=charge2(b[k]); k=mm[k]; } k1=i; if(i>500) return 0; return 1; } int main(){ int t; scanf("%d",&t); while(t--) { memset(v,0,sizeof(v)); memset(b,0,sizeof(b)); char a1[5]; scanf("%d%d%d",&n,&c,&m); for(int i=0;i<m;i++) { scanf("%s",a1); a[i]=charge1(a1[0]); } sort(a,a+m); if(n==0) { if(a[0]) printf("So Sorry.\n"); else printf("0\n"); continue; } if(dfs()&&visit()) { for(int i=k1-1;i>=0;i--) printf("%c",c1[i]); printf("\n"); } else printf("So Sorry.\n"); } return 0; }