超级密码
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1492 Accepted Submission(s): 445
密码是一个C进制的数,并且只能由给定的M个数字构成,同时密码是一个给定十进制整数N(0<=N<=5000)的正整数倍(如果存在多个满足条件的数,那么最小的那个就是密码),如果这样的密码存在,那么当你输入它以后门将打开,如果不存在这样的密码......那就把门炸了吧.
注意:由于宝藏的历史久远,当时的系统最多只能保存500位密码.因此如果得到的密码长度大于500也不能用来开启房门,这种情况也被认为密码不存在.
注意:在给出的M个数字中,如果存在超过10的数,我们约定用A来表示10,B来表示11,C来表示12,D来表示13,E来表示14,F来表示15.我保证输入数据都是合法的.
注意:构成密码的数字不一定全部都要用上;密码有可能非常长,不要试图用一个整型变量来保存密码;我保证密码最高位不为0(除非密码本身就是0).
22 10
3
7 0 1
2 10
1
1
25 16
3
A B C
give me the bomb please
CCB
Hint
Huge input, scanf is recommended.
r= k (mod c)則 (k*p+a)(mod c)=(r*p+a)(mod c)
若是某个数&#20540;序列的余数为r.....若是某个余数已经被机关过...那么后面获得的必然是与本来机关过的余数序列雷同的序列 而由BFS的性质.最短的必然是最先被机关出来的..所以.....先到先得!(每一位应用什么数字都是不变的哦.....就是在同一个数&#20540;凑集内...). 若是看不懂 看下面的
例如 若是 k1%c==k1k2%c 则 k1k3%c==k1k2k3%c
再特别一点的 比如 3%4==3 27%4==3 则 31%4==271%4 ,32%4==272%4 ,33%4==273%4...............
我们请求得的数是n的整数倍 即余数为0 则取余数为0的数中的最小的那个即可
若是请求余数为k的数 只请求出最短的序列 因为n<5000余数最多有5000个 用BFS搜刮 余数第一次呈现的地位就是最短的序列 从中我们找出余数为0对应的最短的序列即可
结论:只要某种余数曾经呈现过.那么这种余数就不须要再呈现..... 直到找到余数为0 或者长度大于500就退出
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue> using namespace std; const int maxn=;
const int maxm=; bool mod[maxm];
char arr[];
int digit[]; struct Node
{
char str[maxn];
int len;
}ans; int N,C,M; int judge(Node X)
{
int sum=;
int len=X.len;
int OK=;
for(int i=;i<len;i++)
{
if(X.str[i]!='')
{
OK=;
break;
}
}
if(!OK) return ;
for(int i=;i<len;i++)
{
if(X.str[i]>=''&&X.str[i]<='')
{
sum=(sum*C+(X.str[i]-''))%N;
}
else if(X.str[i]>='A'&&X.str[i]<='F')
{
sum=(sum*C+(X.str[i]-'A'+))%N;
}
}
sum=sum%N;
return sum;
} queue<Node> q; int bfs()
{ Node x,y; while(!q.empty())
{ y=q.front();
q.pop();
int MOD1; // if(y.len==3&&y.str[0]=='1'&&y.str[1]=='1'&&y.str[0]=='0') cout<<"miaomiaoishere\n"; if((MOD1=judge(y))==)
{
ans=y;
int len=ans.len;
for(int i=;i<len;i++)
printf("%c",ans.str[i]);
putchar();
return ;
}
int zero=;
// if(y.len==1) zero=1;
for(int i=zero;i<;i++)
{
if(digit[i])
{
x=y;
if(i>=&&i<)
x.str[x.len]=i+'';
else if(i>=&&i<=)
x.str[x.len]=i-+'A';
x.len=x.len+;
int MOD2=judge(x);
if(x.len+<=&&mod[MOD2]==false&&MOD2!=)
{
mod[MOD2]=true;
q.push(x);
}
}
}
}
return ;
} int main()
{int T;
scanf("%d",&T);
while(T--)
{
memset(mod,false,sizeof(mod));
memset(digit,,sizeof(digit));
while(!q.empty()) q.pop(); scanf("%d%d%d",&N,&C,&M);
getchar();
for(int i=;i<M;i++)
{
scanf("%c",&arr[i]);
getchar();
if(arr[i]<=''&&arr[i]>='')
digit[arr[i]-'']=;
else if(arr[i]<='F'&&arr[i]>='A')
digit[arr[i]-'A'+]=;
}
Node xt;
for(int i=;i<=;i++)
{
if(digit[i])
{
if(i>=&&i<)
xt.str[]=i+'';
else if(i>=&&i<=)
xt.str[]=i-+'A';
xt.len=;
q.push(xt);
// int MOD=judge(xt);
// mod[MOD]=true;
}
}
// cout<<q.size()<<"----------\n";
// getchar(); if(N==)
{
if(digit[]) puts("");
else puts("give me the bomb please");
}
else
{
if(bfs())
{
}
else
puts("give me the bomb please");
} } return ;
}