标签:
按照数的位数BFS,从小向大枚举就可以保证构造出来的数是递增的,如果不加判断就直接搜索的话,复杂度非常高。因此需要剪枝。
优化方法:如果一个数%N==0,那么这个数就是N的倍数。在没有找到的前提下,如果A%N==B%N,而且A<B,那么其实我们就可以取A而不取B,因为如果在A末尾增加C可以使得AC%N==0,那么BC%N也等于0,易得:如果A和B追加数之后%N==0,那么最优条件下追加的数肯定相同。
因此我们只需要维护组合出来的数%N的值即可,如果在搜索的途中出现了相同的%N值,就可以直接忽略了,因为肯定没有前面的优秀。
/***************/
1 #include<stdio.h> 2 #include<string> 3 #include<queue> 4 #include<string.h> 5 #include<algorithm> 6 #define mem(a) memset(a,0,sizeof(a)) 7 using namespace std; 8 const int MAXN=1e4+10; 9 int vis[MAXN],del[MAXN],pre[MAXN]; 10 char al[MAXN]; 11 int n; 12 void print_ans(){ 13 int r=0; 14 string ans; 15 while(ans.empty()||r!=0){ 16 ans+=al[r]; 17 r=pre[r];//由于anser的下属是0,刚开始的数字的上司又是0,所以最后找到0结束循环; 18 } 19 reverse(ans.begin(),ans.end()); 20 puts(ans.c_str()); 21 } 22 bool bfs(){ 23 queue<int>dl; 24 dl.push(0); 25 while(!dl.empty()){ 26 int f1,f2; 27 f1=dl.front();//** 28 dl.pop(); 29 for(int i=0;i<=9;i++){ 30 if(del[i]||i==0&&f1==0)continue; 31 f2=(f1*10+i)%n; 32 if(vis[f2])continue;//应该放上面 33 pre[f2]=f1;//** 34 al[f2]=i+‘0‘; 35 if(f2==0){ 36 print_ans(); 37 return true; 38 } 39 vis[f2]=1; 40 dl.push(f2); 41 } 42 } 43 puts("-1"); 44 return false; 45 } 46 int main(){ 47 int m,flot=0; 48 while(~scanf("%d%d",&n,&m)){ 49 mem(vis);mem(del);mem(pre);mem(al); 50 while(m--){ 51 int temp; 52 scanf("%d",&temp); 53 del[temp]=true; 54 } 55 printf("Case %d: ",++flot); 56 bfs(); 57 } 58 return 0; 59 }
Yet Another Multiple Problem(bfs好题)
标签:
原文地址:http://www.cnblogs.com/handsomecui/p/4864836.html