HDU ACM 4474 Yet Another Multiple Problem->数论(数位BFS)

来源:互联网 发布:刑天seo怎么样 编辑:程序博客网 时间:2024/05/24 06:20

题意:n和m,m个十进制的单位数字(0-9),求最小的数ans,使ans是n的倍数(除0),且ans中不包括输入的十进制数字。不存在输出-1。

使用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值,就可以忽略了,肯定没有前面的更好。

#include<iostream>#include<queue>using namespace std;#define N 10010int p[N];      //pre[v]记录到达v的前一节点uint num[N];    //num[v]记录形成v的最后一位数字bool a[10];    //被除去的数据int n;void Init(){memset(p,-1,sizeof(p));memset(num,-1,sizeof(num));memset(a,false,sizeof(a));}void Show(int u)        //递归打印结果{if(p[u]!=-1)Show(p[u]);printf("%d",num[u]);}void bfs(){int i,t,u;queue<int> q;for(i=1;i<10;i++)  //注意0不算,要除去if(!a[i]){t=i%n;if(t==0)             //结果只有一位数字的情况{printf("%d",i);return ;}q.push(t);num[t]=i;}while(!q.empty()){u=q.front();q.pop();for(i=0;i<10;i++)if(!a[i]){t=(10*u+i)%n;if(num[t]==-1) //之前未出现过{q.push(t);p[t]=u;num[t]=i;}if(t==0){Show(t);return ;}}}printf("-1");}int main(){int k=0,m,x;while(scanf("%d%d",&n,&m)==2){Init();while(m--){scanf("%d",&x);a[x]=true;}printf("Case %d: ",++k);bfs();putchar('\n');}return 0;}


0 0
原创粉丝点击