1. 程式人生 > >【POJ】1465Multiple(BFS+同餘剪枝)

【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;
}