POJ 1465-Multiple(BFS-最小整倍數)

kewlgrl發表於2016-07-29

Multiple

Time Limit: 1000MS   Memory Limit: 32768K
Total Submissions: 7106   Accepted: 1524

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


題目意思:

給定一個自然數N,以及M個不同的數字X1,X2,...Xm。求N的最小正整數倍數,使得滿足這個數的每個數字都是M個數字中的其中一個。

解題思路:

BFS廣搜。
思路:利用給定的M個數,組成不同的數,比如7 0 1,可以依0 1 7的序組成0 1 7 10 11 17 77 100 110 111 117……等等等等,然後對這些數進行判斷是否整除N。
注意剪枝

對於給定兩個數A,B,如果A和B模N都相同,設為C,即:

A=x*N+C

B=y*N+C

那麼如果在A後面加上一個數字能夠被N整除,則在B後面加上這個數字也肯定可以被N整除

即:(A*10+X)%N==(B*10+X)%N

因此可以利用模N的結果進行判重,只保留相同餘數的最小數。


注意特判“0”的情況。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=5050;
int n,m;
int digit[10];//給定的M個數字
bool flag[maxn];//剪枝用,標記當前餘數是否出現

struct Node
{
    int digit;//當前狀態的各位值
    int r;//當前狀態值%N的餘數
    int pre;//當前狀態的各位值的連線指標,用來找到所有當前狀態的位
} Q[maxn];

int BFS()
{
    memset(flag,0,sizeof(flag));
    int front=0,tail=1;
    Q[front].digit=0;
    Q[front].r=0;
    Q[front].pre=-1;
    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;//餘數為0表示能整除
            }
        }
        ++front;//佇列遞增加1
    }
    return -1;
}
void print(int ans)
{
    if(ans>0)
    {
        print(Q[ans].pre);
        cout<<Q[ans].digit;
    }
}
int main()
{

    while(cin>>n)
    {
        cin>>m;
        for(int i=0; i<m; i++)
            cin>>digit[i];
        sort(digit,digit+m);//輸入的數列遞增排序
        if(n==0)//特判0
        {
            puts("0");
            continue;
        }
        int ans=BFS();//廣搜
        if(ans==-1) puts("0");//不存在
        else
        {
            print(ans);
            puts("");//輸出格式
        }
    }
    return 0;
}
/**
22
3
7
0
1

2
1
1
**/


相關文章