题意:给出n,c,m,密码必须是n这个十进制数的整数倍,c代表这个密码是C进制数,m代表这个密码只有m种字符构成,而且密码不能长于500
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#define N 20
using namespace std;
struct Node
{
int s[505];
int len;
};
int num[20];
int vis[5005];
int n,c,m,t;
/**由于数可能会很大,所以取余*/
int mod(Node nd)
{
int tp = 0;
for(int i = 0;i < nd.len;i++)
{
//c为进制
tp = (tp*c+nd.s[i])%n;
}
return tp;
}
//打印结果
void mprintf(Node nd)
{
for(int i = 0;i < nd.len;i++)
{
if(nd.s[i] > 9)
printf("%c", nd.s[i]+'A'-10);
else printf("%d", nd.s[i]);
}
printf("\n");
}
int bfs()
{
Node nd;
nd.len = 0;queue<Node> Q;
//数的第一位不能为零,所以从一开始
for(int i = 1;i < 16;i++)
{
if(num[i])
{
nd.s[0] = i;
nd.len = 1;
int r = mod(nd);//求余
if(r == 0)//表示整除
{
mprintf(nd);
return 1;
}
else
{
if(!vis[r])//检查该余数之前是否出现过,若没有出现过,加到队列
{
vis[r] = 1;
Q.push(nd);
}
}
}
}
while(!Q.empty())
{
nd = Q.front();
Q.pop();
for(int i = 0;i < 16;i++)
{
if(num[i])
{
nd.s[nd.len] = i;
nd.len++;
int r = mod(nd);
if(r == 0)
{
mprintf(nd);
return 1;
}
else
{
if(!vis[r] && nd.len < 500)
{
vis[r] = 1;
Q.push(nd);
}
}
nd.len--;
}
}
}
return 0;
}
int main()
{
scanf("%d", &t);
while(t--)
{
scanf("%d%d%d", &n, &c, &m);
memset(num, 0, sizeof(num));
memset(vis, 0, sizeof(vis));
for(int i = 0;i < m;i++)
{
char c;
scanf(" %c", &c);
if(c >= '0' && c <= '9')
num[c - '0'] = 1;
else num[c - 'A' + 10] = 1;
//cout<<"<<<<<<"<<endl;
}
//cout<<"<<<<<<"<<endl;
if(n != 0)
{
int flag = bfs();
if(flag == 0)
printf("give me the bomb please\n");
}
else
{
//如果n == 0 那么只有零本身是他的倍数
if(num[0])
printf("0\n");
else
printf("give me the bomb please\n");
}
}
return 0;
}