• Multiple_BFS + 余数判重


    Time Limit: 1000MS   Memory Limit: 32768K
    Total Submissions: 7211   Accepted: 1545

    Description

    a program that, given a natural number N between 0 and 4999 (inclusively), and M distinct decimal digits X1,X2..XM (at least one), finds the smallest strictly positive multiple of N that has no other digits besides X1,X2..XM (if such a multiple exists).

    Input

    The input has several data sets separated by an empty line, each data set having the following format: 

    On the first line - the number N 
    On the second line - the number M 
    On the following M lines - the digits X1,X2..XM.

    Output

    For each data set, the program should write to standard output on a single line the multiple, if such a multiple exists, and 0 otherwise. 

    An example of input and output:

    Sample Input

    22
    3
    7
    0
    1
    
    2
    1
    1

    Sample Output

    110
    0

    余数判重

    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 先出现的值小。所以后出现的同余的数 就不用搜索了。。

    因此可以余数判重后剪枝。。。。

    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    #include<queue>
    #include<algorithm>
    #include<stdlib.h>
    using namespace std;
    struct node
    {
        int pre,r,digit;
    };
    node qu[5500];
    int n,m,a[5500];
    int vis[5500];
    void print(int head)//输出
    {
        if(head==-1)return;
        print(qu[head].pre);
        printf("%d",qu[head].digit);
    }
    
    void bfs()
    {
        if(!n)//n为0输出0并返回
        {
            cout<<0<<endl;
            return;
        }
        memset(vis,0,sizeof(vis));//用来标记余数
        int rear,front;
        front=rear=0;
        for(int i=1;i<=m;i++)
        {
            if(a[i]==0) continue;
            node p;
            p.digit=a[i];p.pre=-1;p.r=a[i]%n;
            qu[rear++]=p;
        }
        while(front<rear)
        {
            node p=qu[front];
            node q;
            if(p.r==0)
            {
                print(front);
                puts("");
                return;
            }
            for(int i=1;i<=m;i++)
            {
                q.digit=a[i];
                q.pre=front;
                q.r=(p.r*10+a[i])%n;
                if(!vis[q.r])
                {
                    qu[rear++]=q;
                    vis[q.r]=1;
                }
            }
            front++;
        }
        puts("0");
        return;
     }
    
    bool cmp(int a,int b)
     {
         return a<b;
     }
    int main()
    {
        while(~scanf("%d",&n))
        {
            scanf("%d",&m);
            for(int i=1;i<=m;i++)
            {
                scanf("%d",&a[i]);
            }
            sort(a+1,a+1+m,cmp);
            bfs();
        }
        return 0;
    }
  • 相关阅读:
    property里的参数
    property关键字的理解
    OC与C语言的几点区别
    C语言学习心得
    QQ第三方<接口>
    为什么选择Redis
    版本控制器
    url传参及重定向
    开发的四个环境
    Paxos分析
  • 原文地址:https://www.cnblogs.com/iwantstrong/p/5776640.html
Copyright © 2020-2023  润新知