广搜题,余数定理:(m+k)%n == (m%n+k)%n
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <string>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
int N, C, M; //输入
bool digit[20]; //数字是否能使用
bool vis[5005]; //访问数组
//字符串s表示的数对N取余
int mod(string s)
{
int temp = 0;
for (int i = 0; i < s.size(); i++)
{
temp = (temp * C + (int)s[i]) % N;
}
return temp;
}
//输出字符串s表示的数
void output(string s)
{
for (int i = 0; i < s.size(); i++)
{
printf("%X", (int)s[i]);
}
cout << endl;
}
//广搜
bool bfs()
{
queue<string> q;
string a, b;
for (int i = 1; i <= 15; i++)
{
if (digit[i])
{
a = (char)i;
if (mod(a) == 0)
{
output(a);
return false;
}
q.push(a);
}
}
while (!q.empty())
{
a = q.front();
q.pop();
for (int i = 0; i <= 15; i++)
{
if (digit[i] && a.size() + 1 <= 500)
{
b = a + (char)i;
int rem = mod(b);
if (rem == 0)
{
output(b);
return false;
}
else
{
if (vis[rem] == 0)
{
vis[rem] = 1;
q.push(b);
}
}
}
}
}
return true;
}
int main()
{
int T;
cin >> T;
while (T--)
{
memset(digit, 0, sizeof(digit));
memset(vis, 0, sizeof(vis));
cin >> N >> C >> M;
int num; //能使用的数字
for (int i = 0; i < M; i++)
{
scanf("%x", &num); //需要十六进制读取输入
digit[num] = true;
}
if (N == 0)
{
if (digit[0])
cout << 0 << endl;
else
cout << "give me the bomb please" << endl;
continue;
}
if (bfs())
cout << "give me the bomb please" << endl;
}
return 0;
}