Multiple

poj1465:http://poj.org/problem?id=1465

题意:给你一个数n(0~4999);以及m个不同十进制的数,问有这些十进制数组成的最小的n的倍数是多少。如果有则输出,没有就输出0;

题解:此题用BFS 。。这个题好在 用 余数判重剪枝。。BFS 如果不加以剪枝,一定会搜索的情况会很庞大。所以应该用余数判重 。
为什么可以用余数判重?
   A=a*N +e 即A%N =e
   B= b*N+e即B%N=e
当A  B mod N的余数相同时,如果先出现A 。在A  后加上一个数 i 时 ,  新的数   C = 10 *a*N + 10 *e+i;同样  B后加上数 i 时 , D = 10*b*N +10*e+i;    由于C D 前边 10*a*N 和 10*b*N 都是N的倍数 ,则C D mod N 的余数都是有 10*e+i 决定的。于是 C D  mod N 同余。因此 A B 同余 都添加上 i 之后 新的两个数C D也是同余的。在无论添加多少个数,新生成的两个数也是同余的。因此 在A 之后如果不出现 N的倍数 ,则在B之后也不会出现。 在A 之后出现,那B之后也会出现。  有因为要求求最小值。所以只需要搜索min(A,B)之后的 ,对于另外一个数之后就不用搜索了。因为对M个排序后,先填入的是小的值,所以 A B 先出现的值小。所以后出现的同余的数 就不用搜索了。因此可以余数判重后剪枝。。。。

 1 #include<cstdio>
 2 #include<stdlib.h>
 3 #include<queue>
 4 #include<cstring>
 5 #define INF 1000000000
 6 using namespace std;
 7 int n,m,d[150]; //d数组用来储存m个数
 8 struct point{
 9     int yu;//记录余数
10     int pre;//记录来自哪一层
11     int now; //记录当前的是哪一个d【i】;
12 }que[10000];
13 int cmp(const void * a,const void * b){
14     int * aa=(int *)a;
15     int * bb=(int *)b;
16     return *aa-*bb;
17 }   //比较器从小到大
18 void print(int tem){
19     if(que[tem].pre!=-1){
20         print(que[tem].pre);
21         printf("%d",que[tem].now);
22     }
23 }//递归输出
24 int bfs(){
25     int front=0,rear=0;
26     int flag[5010];//标记是否访问
27     que[rear].now=0;
28     que[rear].pre=-1;
29     que[rear++].yu=0;
30     memset(flag,0,sizeof(flag));
31     while(front<rear){
32         struct point tem;
33         tem=que[front];
34         for(int i=0;i<m;i++){
35             int temp=(tem.yu*10+d[i])%n;
36             if(!flag[temp] && (tem.pre!=-1 || d[i]>0)){
37                 struct point st;
38                 st.now=d[i];
39                 st.yu=temp;
40                 st.pre=front;
41                 flag[temp]=1;
42                 que[rear++]=st;
43                 if(temp==0){
44                     print(rear-1);
45                     printf("
");
46                     return 1;
47                 }
48             }
49         }
50         front++;
51     }
52     return 0;
53 }//在大脑中一定要有完整清晰的思路。
54 int main(){
55     int i;
56     while(scanf("%d",&n)!=EOF){
57         scanf("%d",&m);
58         for(i=0;i<m;i++)
59             scanf("%d",&d[i]);
60         qsort(d,m,sizeof(d[0]),cmp);
61         if(n==0){
62             printf("0
");
63         }
64         else if(!bfs())
65             printf("0
");
66     }
67 }
View Code
原文地址:https://www.cnblogs.com/chujian123/p/3366457.html