超级密码
题目链接:HDU - 1226题意:给出一个N;求出一个最小的C进制数X, 使得X是N的正整数倍数, 且X只能由给出的M个个位数组成;
同余剪枝, 和poj1456一样, 不过多了一个C进制, 并要求结果不超过500位;
代码感觉很神奇, que数组开小了会TE, 开到40000左右才行, 用vector也TE了, 改着改着突然就AC了, 弄得我很懵;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n, c, m;
int digit[20];
struct node{
int now, pre, mod, len;
}que[40000];
int vis[6000];
void print(int k){
if(k==0) return;
print(que[k].pre);
if(que[k].now<=9) printf("%c", que[k].now+'0');
else printf("%c", (que[k].now-10+'A'));
}
void bfs(){
memset(vis, 0, sizeof(vis));
int head=0,tail=0;
node tmp;
tmp.now=0;
tmp.len=0;
tmp.mod=0;
tmp.pre=-1;
que[tail++]=tmp;
while(head<tail){
tmp=que[head];
for(int i=0; i<m; i++){
if(tmp.pre==-1&&digit[i]==0) continue;
int tmod=(tmp.mod*c+digit[i])%n;
if(vis[tmod]) continue;
node p;
if(tmod==0){
p.mod=tmod;
p.len=tmp.len+1;
p.now=digit[i];
p.pre=head;
que[tail++]=p;
print(tail-1);
printf("\n");
return;
}
p.mod=tmod;
p.len=tmp.len+1;
p.now=digit[i];
p.pre=head;
if(p.len>=500) continue;
que[tail++]=p;
}
head++;
}
printf("give me the bomb please\n");
return;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d%d", &n, &c, &m);
char x;
int flag=0;
for(int i=0; i<m; i++){
getchar();
scanf("%c", &x);
if(x<='9'&&x>='0') digit[i]=(x-'0');
else digit[i]=(x-'A')+10;
if(digit[i]==0) flag=1;
}
sort(digit, digit+m);
if(n==0){
if(flag) printf("0\n");
else printf("give me the bomb please\n");
continue;
}
bfs();
}
return 0;
}