password box
Time Limit: 2000 ms | Memory Limit: 65535 KB
Difficulty: 3
describe
Little M got a treasure box, but unfortunately, a set of magical passwords is required to open the treasure box, but under the treasure box
There are hints about the password: the password is a C-base number, and can only be composed of some of the given M numbers, the password does not exceed 500 digits, and the password is a positive integer with a given decimal integer N times,
If such a code exists, then you can open the treasure box and get the treasure, if not
Such a password...then you can only collect this treasure box.
enter
Enter a T, indicating that there are T groups of test data, (T≤500)
then enter N, C, M (N, C, M as described above) ( 0≤N≤5000, 1≤M≤16 , 2≤C ≤16 )
and then M numbers, indicating which numbers are contained in the password. (The input is guaranteed to be legal)
Use A to represent 10, B to represent 11, C to represent 12, D to represent 13, E to represent 14, F to represent 15
output
Output: If the password exists, enter the smallest one is the password, and there is no "So Sorry." (the password does not contain leading zeros)
sample input
3
22 10 3
7 0 1
2 10 1
1
25 16 3
A B C
Sample output
110
So Sorry.
CCB
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
//Looking at the idea of the great god, simulating the arithmetic operation of division, it can be seen that if there is the same remainder, a loop will occur, and the search status can be marked with the remainder
//mark mark, pre is the record path for finding the answer, ansAt: num
int mark[5005 obtained when res is i ],pre[5004],ansAt[5005],N,C,M,num[20];
char ans[5005];//Record the answer
char itoc(int i)
{
return i<10?(i+'0'):(i+'A'-10);
}
int ctoi(char i)
{
return i>='0'&&i<='9'?(i-'0'):(i-'A'+10);
}
bool bfs()
{
queue<int> q;
q.push(0);
while(!q.empty())
{
int temp=q.front();
q.pop();
for(int i=0; i<M;++i)
{
int res=(temp*C+num[i])%N;//The same remainder means repeated search
if(!mark[res]&&!(!temp&&!num[i] ))//Note that when temp and num are both 0, the remainder cannot be used to judge
{
mark[res]=true;
ansAt[res]=num[i];
pre[res]=temp;
if(res==0) //If the remainder is 0, it is divisible, find the answer
return true;
q.push(res);
}
}
}
return false;
}
bool check()
{
int temp=pre[0],i=0;
ans[i++]=itoc(ansAt[0]);
while(temp) //Construct result according to pre and ansAt
{
ans[i++]=itoc( ansAt[temp]);
temp=pre[temp];
}
ans[i]=0;
if(i<=500) //The correct result is less than 500 digits
return true;
return false;
}
int main()
{
int T;
string str;
cin>>T;
while(T--)
{
memset(mark,false,sizeof(mark));
memset(pre,0,sizeof(pre));
cin>> N>>C>>M;
for(int i=0;i<M;++i)
{
cin>>str; //The input may have hexadecimal characters, so the input is defined as string type, When converting to int type
num[i]=ctoi(str[0]); //char->int; When the input is less than 10, there is only one number per input, that is,
//that is, the first character str [0], when the letter is, the same way
}
sort(num,num+M); //sort to search from small to large
if(N==0)
{
if(num[0]==0) //0 Is to judge
cout<<'0'<<endl;
else
cout<<"So Sorry."<<endl;
continue;
}
if(bfs()&&check()) // found and the length is legal
{
for(int i=strlen(ans)-1;i>=0;--i)
cout<<ans[i];
cout<<endl;
}
else
cout<<"So Sorry."<<endl;
}
return 0;
}
Others don't understand too much. . Save it first