【POJ】1465Multiple(BFS+同余剪枝)

Time Limit: 1000MS   Memory Limit: 32768K
Total Submissions: 8365   Accepted: 1850

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

Source

Southeastern Europe 2000

 题目大意:给你一个数n(0~4999),和m个数(0~9),现在要求你输出一个数k,这个k是N的最小公倍数,并且要求这个k只能由前面给出的m个数组成。

 思路:首先知道如果存在这样的数k,那么这个k一定是有我们给定的m个数组成的,那么这样我们只需要每层枚举就好了,也就是每一位数的枚举。

例如:给定 1 3 5:,可以得到:1 3 5 11 13 15 31 33 35 51 53 55 135 153 315 351 513 531这样的几个数,

这样枚举起来,实际上有很多的不必要的,比如15 和后面的额135 他们是9倍的关系,如果15不是最小公倍数,那么135也一定不是,当然不一定枚举到那个位置,但是其中的道理就是这样的,其中有些无序枚举的,

这里,我们就用flag数组保存一下每一次的余数,只要是余数相同的,就不需要再次枚举了,因为他一定不是,其实和vis数组基本一样的,然后就是代码实现,

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn=5000+50;
int n,m;
int digit[10];
bool flag[maxn];

struct Node
{
    int digit,r,pre;
}Q[maxn];

int BFS()
{
    memset(flag,0,sizeof(flag));
    int front=0,tail=1;
    Q[front].r=0;
    Q[front].pre=-1;
    Q[front].digit=0;

    while(front<tail)
    {
        Node node=Q[front];
        int r=node.r;
        for(int i=0;i<m;i++)
        {
            int nr=(r*10+digit[i])%n;

            if(!flag[nr]&&(node.pre!=-1||digit[i]!=0)) //如果后一位加上的是0,那么也就不用加了,肯定同余,肯定不是
            {
                flag[nr]=true;
                node.r=nr;
                node.digit=digit[i];
                node.pre=front;
                Q[tail++]=node;
                
                if(nr==0) return tail-1;
            }
        }
        front++;
    }
    return -1;
}

void print(int ans)
{
    if(ans>0)
    {
        print(Q[ans].pre);
        printf("%d",Q[ans].digit);
    }
}

int main()
{
    while(scanf("%d",&n)==1)
    {
        scanf("%d",&m);
        for(int i=0;i<m;i++)
            scanf("%d",&digit[i]);
        if(n==0) {printf("0\n");continue;}
        sort(digit,digit+m);
        int ans=BFS();
        
        if(ans==-1) printf("0\n");
        else
        {
            print(ans);
            puts("");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wentong_Xu/article/details/84312579