【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
題目大意:給你一個數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;
}