超级密码
Time Limit : 20000/10000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 4 Accepted Submission(s) : 0
Problem Description
Ignatius花了一个星期的时间终于找到了传说中的宝藏,宝藏被放在一个房间里,房间的门用密码锁起来了,在门旁边的墙上有一些关于密码的提示信息:
密码是一个C进制的数,并且只能由给定的M个数字构成,同时密码是一个给定十进制整数N(0<=N<=5000)的正整数倍(如果存在多个满足条件的数,那么最小的那个就是密码),如果这样的密码存在,那么当你输入它以后门将打开,如果不存在这样的密码......那就把门炸了吧.
密码是一个C进制的数,并且只能由给定的M个数字构成,同时密码是一个给定十进制整数N(0<=N<=5000)的正整数倍(如果存在多个满足条件的数,那么最小的那个就是密码),如果这样的密码存在,那么当你输入它以后门将打开,如果不存在这样的密码......那就把门炸了吧.
注意:由于宝藏的历史久远,当时的系统最多只能保存500位密码.因此如果得到的密码长度大于500也不能用来开启房门,这种情况也被认为密码不存在.
Input
输入数据的第一行是一个整数T(1<=T<=300),表示测试数据的数量.每组测试数据的第一行是两个整数N(0<=N& lt;=5000)和C(2<=C<=16),其中N表示的是题目描述中的给定十进制整数,C是密码的进制数.测试数据的第二行是一个整数 M(1<=M<=16),它表示构成密码的数字的数量,然后是M个数字用来表示构成密码的数字.两个测试数据之间会有一个空行隔开. 注意:在给出的M个数字中,如果存在超过10的数,我们约定用A来表示10,B来表示11,C来表示12,D来表示13,E来表示14,F来表示15.我保证输入数据都是合法的.
Output
对于每组测试数据,如果存在要求的密码,则输出该密码,如果密码不存在,则输出"give me the bomb please". 注意:构成密码的数字不一定全部都要用上;密码有可能非常长,不要试图用一个整型变量来保存密码;我保证密码最高位不为0(除非密码本身就是0).
Sample Input
3 22 10 3 7 0 1 2 10 1 1 25 16 3 A B C
Sample Output
110 give me the bomb please CCB [hint]Hint[/hint] Huge input, scanf is recommended.
ac代码:
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
const int MAXN=;
int num[];
struct Node{
int s[MAXN];
int len;
};
int M,C,N;
int vis[];
int mod(Node a){
int x=;
for(int i=;i<a.len;i++){
x=(x*C+a.s[i])%N;
}
return x;
}
void print_ans(Node a){
for(int i=;i<a.len;i++){
if(a.s[i]>=&&a.s[i]<=)printf("%c",a.s[i]+'');
else printf("%c",a.s[i]-+'A');
}
puts("");
}
void bfs(){
memset(vis,,sizeof(vis));
queue<Node>dl;
Node a;
a.len=;
int md;
for(int i=;i<M;i++){
a.s[]=num[i];
md=mod(a);
//printf("%d ",md);
if(vis[md]||num[i]==)continue;
if(md==&&num[i]){
printf("%d\n",num[i]);
return;
}
// printf("%d ",md);
vis[md]=;
dl.push(a);
}
while(!dl.empty()){
a=dl.front();
dl.pop();
for(int i=;i<M;i++){
if(a.len==&&a.s[]==)continue;
a.s[a.len]=num[i];
a.len++;
//puts("**");
md=mod(a);
// printf("%d ",md);
if(vis[md]||a.len>){
a.len--;//这里少了这个错的啊。。。。。无奈。。。。。
continue;
}
// print_ans(a);
if(md==){ print_ans(a);
return;
}
vis[md]=;
dl.push(a);
a.len--;
}
}
puts("give me the bomb please");
}
int main(){
int T;
scanf("%d",&T);
char s[];
while(T--){
scanf("%d%d%d",&N,&C,&M);
for(int i=;i<M;i++){
scanf("%s",s);
if(s[]>=''&&s[]<='')num[i]=s[]-'';
else num[i]=s[]-'A'+;
// printf("%d ",num[i]);
}
sort(num,num+M);
if(N)bfs();
else if(!num[])puts("");
else puts("give me the bomb please");
}
return ;
}
wa代码,求改正。。。。
感觉没错啊;
代码:
#include<stdio.h>
#include<string>
#include<queue>
#include<string.h>
#include<algorithm>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
const int MAXN=1e4+;
int cmp(char a,char b){
/*if(a<b)return 1;
else return 0;*/
return a<b;
}
int vis[MAXN],pre[MAXN];
char num[];
int nu[];
char al[MAXN];
int n,m,C;
void print_ans(){
int r=;
string ans;
while(ans.empty()||r!=){
ans+=al[r];
r=pre[r];
}
reverse(ans.begin(),ans.end());
puts(ans.c_str());
}
void bfs(){
queue<int>dl;
dl.push();
while(!dl.empty()){
int f1,f2;
f1=dl.front();//**
dl.pop();
for(int i=;i<m;i++){
if(nu[i]==&&f1==)continue;
f2=(f1*C+nu[i])%n;
if(vis[f2])continue;
pre[f2]=f1;
al[f2]=num[i];
if(f2==){
//printf("%d %d\n",f1,f1*C+nu[i]);
print_ans();
return;
}
vis[f2]=;
dl.push(f2);
}
}
puts("give me the bomb please");
}
int main(){
int T;
scanf("%d",&T);
while(T--){
mem(vis);mem(pre);mem(al);
char x[];
scanf("%d%d%d",&n,&C,&m);
for(int i=;i<m;i++){
scanf("%s",x);
num[i]=x[];
//printf("%c ",num[i]);
}
sort(num,num+m);
int o=;
for(int i=;i<m;i++){
if(num[i]>='A'&&num[i]<='Z')nu[i]=+num[i]-'A';
else nu[i]=num[i]-'';
if(num[i]=='')o=;
//printf("%c %d ",num[i],nu[i]);
}
if(n!=)bfs();
else if(o)puts("");
else puts("give me the bomb please");
}
return ;
}