题意:0-9这十个数字里面的若干个数字组合出一个数,使这个数是N的倍数,求最小的这个这样的数,不存在的话输出-1。
按照数的位数BFS,从小向大枚举就可以保证构造出来的数是递增的,如果不加判断就直接搜索的话,复杂度非常高。因此需要剪枝。
参考http://blog.youkuaiyun.com/yang_7_46/article/details/12356587
注意为什么这个地方如果同余就不进行搜索的原因。。
int cnt,vis[N];
int del[20];
int num[20];
struct Node{
int c;
int pre,cur;
}q[N];
vector<int>res;
void print(int id){
res.push_back(q[id].c);
int last=q[id].pre;
if(last)print(last);
}
int main(){
int cas=0;
int n,m;
//freopen("in.txt","r",stdin);
while(~sf("%d%d",&n,&m)){
pf("Case %d: ",++cas);
cnt=0;mem(del,0);mem(vis,0);res.clear();
rep(i,1,m){int x;sf("%d",&x);del[x]=1;}
rep(i,0,9){if(!del[i])num[++cnt]=i;}
int head=1,tail=1;
q[1].cur=0,q[1].pre=0;
int ok=0,ans=0;
while(head<=tail){
int u=q[head++].cur;
for(int i=1;i<=cnt;++i){
if(num[i]==0&&u==0)continue;
int v=(u*10+num[i])%n;
if(vis[v])continue;
vis[v]=1;
if(vis[0]){res.push_back(num[i]);ans=head-1;ok=1;break;}
q[++tail].pre=head-1;
q[tail].cur=v;
q[tail].c=num[i];
}
if(ok)break;
}
if(!ok)puts("-1");
else {
print(ans);
for(int i=res.size()-2;i>=0;--i)pf("%d",res[i]);puts("");
}
}
}