POJ-1465-bfs,同余剪枝

来源:互联网 发布:淘宝改差评怎么改 编辑:程序博客网 时间:2024/06/10 20:10

题目大意:给定一个数n,和m个数,问求n的最小倍数使得这个数的每一位都是那m个数中的;

题目解析:开始想的肯定是将这m个数慢慢dfs过去,注意如果bfs过程中如果遇到当前余数已经被发现就应该剪枝(同余定理),因为之前那个数肯定小,并且如果可以生成可行解也一定在之前那个数的基础上;

AC代码:

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>using namespace std;const int maxn = 5050;int n,m,num[maxn];bool vis[maxn];struct node{intpre,r,dig;node(int a,int b,int c){dig=a;r=b;pre=c;}node(){pre=r=dig=0;}}q[maxn];int bfs(){int front=0,tail=1;q[front].pre=-1;q[front].r=0;q[front].dig=0;while(front<tail){for(int i=0;i<m;i++){int t=(10*q[front].r+num[i])%n;if(vis[t]||(num[i]==0&&q[front].pre==-1))continue;vis[t]=1;q[tail].pre=front;q[tail].dig=num[i];q[tail++].r=t;if(t==0)return tail-1;}front++;}return -1;}void pri(int index){if(q[index].pre==-1)return ;pri(q[index].pre);printf("%d",q[index].dig);}int main(){while(scanf("%d%d",&n,&m)!=EOF){memset(vis,0,sizeof(vis));for(int i=0;i<m;i++)scanf("%d",&num[i]);sort(num,num+m);if(n==0){printf("0\n");continue;}int ans=bfs();if(ans==-1)printf("0");else pri(ans);puts("");}return 0;}

0 0