hdu 1226 广搜
题意:密码是一个C进制的数,并且只能由给定的M个数字构成,同时密码是一个给定十进制整数N
(0<=N<=5000)的正整数倍(如果存在多个满足条件的数,那么最小的那个就是密码), 最多只能保存
500位密码.因此如果得到的密码长度大于500也不能用来开启房门,这种情况也被认为密码不存在.
分析:广搜, 结构体记录 密码下标、前驱、余数、长度。
每次(余数*进制+新数)%N 求得新的余数,若为0,则找到密码,若超过500位,则无解。
余数如果以前出现过,则舍弃。
bool b[15010]; char c[20]; int a[20]; int T,N,C,M,p; struct node{ int pre,id,r,len; }nd[15005]; queue<int> q; int bfs(){ for(int i=0;i<M;i++) if(a[i]&&b[a[i]%N]==0){ b[a[i]%N]=1; nd[p].id=i; nd[p].r=a[i]%N; nd[p].pre=-1; nd[p].len=1; if(nd[p].r==0)return p; q.push(p); p++; } while(!q.empty()){ int v=q.front(); q.pop(); for(int i=0;i<M;i++){ if(b[(nd[v].r*C+a[i])%N]==0){ b[(nd[v].r*C+a[i])%N]=1; nd[p].id=i; nd[p].r=(nd[v].r*C+a[i])%N; nd[p].pre=v; nd[p].len=nd[v].len+1; if(nd[p].r==0)return p; if(nd[p].len<500){ q.push(p); p++; } } } } return -1; } void shuchu(int i){ if(nd[i].pre!=-1) shuchu(nd[i].pre); cout<<c[nd[i].id]; } void solve(){ if(N==0){ if(a[0]==0)cout<<0<<endl; else cout<<"give me the bomb please"<<endl; return; } int s=bfs(); if(s==-1){ cout<<"give me the bomb please"<<endl; return; } shuchu(s); cout<<endl; } void read(){ p=0; memset(b,0,sizeof b); while(!q.empty())q.pop(); scanf("%d%d%d",&N,&C,&M); for(int i=0;i<M;i++){ //cout<<" "<<M<<endl; //scanf("%c",&c[i]); cin>>c[i]; if(c[i]>='0'&&c[i]<='9')a[i]=c[i]-'0'; else a[i]=c[i]-'A'+10; } //cout<<T<<' '<<N<<' '<<C<<' '<<M<<' '<<c[0]<<' '<<c[1]<<' '<<c[2]<<endl; sort(a,a+M); sort(c,c+M); } int main(){ scanf("%d",&T); while(T--){ read(); solve(); } return 0; }