• 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
  • 相关阅读:
    战火魔兽CJQ圣印问题
    sublime插件总汇
    js引用类型
    一、vue的数据双向绑定的实现
    渲染机制
    帆布指纹识别
    call、apply与bind在理解
    webpack的世界
    line-height与vertical-align
    'abc' 转换成[a, b, c]一道面试题的思考
  • 原文地址:https://www.cnblogs.com/chujian123/p/3366457.html
Copyright © 2020-2023  润新知