#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define MAXN 555
#define MAXM 5555
/*
先解释下,这个是用bfs广度搜索是否成立,不断让那些数字打入数组num,看是否成立
大数模运算,只要成立就输出退出,不成立就继续,因为不能有重复的余数,所以不会死循环
不能有重复的余数,不然会死循环
*/
struct Node{
int num[MAXN];//打入这个数组
int len;
};
bool digit[22];//纪录可以用这个数
bool mark[MAXM];
int N,C,M;
//判断C进制的密码转10进制能否被N整除,大数模法
int Judge(Node &p){
int len=p.len,tmp=0;
for(int i=1;i<=len;i++){
tmp=(tmp*C+p.num[i])%N;
}
return tmp;
}
bool bfs(){
memset(mark,false,sizeof(mark));//标记是否出现过这样的余数
queue<Node>Q;
Node p,q;
p.len=1;
Q.push(p);
while(!Q.empty()){
p=Q.front();//p用于广搜循环
Q.pop();
for(int i=p.len==1?1:0;i<16;i++)//首位不为0
{
if(digit[i])
{
q=p;//q进行改变,为了入栈
q.num[q.len]=i;
int mod=Judge(q);
if(mod)//如果余数不为0
{if(!mark[mod])//如果此余数没出现过,标记上,q入栈
{
mark[mod]=1;
q.len++;
Q.push(q);
}}
else
{
for(int i=1;i<=q.len;i++)
printf("%X",q.num[i]);
printf("\n");
return true;
}
}
}
}
return false;
}
int main(){
int _case,x;
scanf("%d",&_case);
while(_case--){
scanf("%d%d%d",&N,&C,&M);
memset(digit,false,sizeof(digit));
for(int i=1;i<=M;i++){
scanf("%x",&x);
digit[x]=true;
}
if(N==0){
if(digit[0])puts("0");
else puts("give me the bomb please");
}else if(!bfs()){
puts("give me the bomb please");
}
}
return 0;
}
HDU1226 超级密码
最新推荐文章于 2018-08-20 11:47:53 发布