給你一個數n 然後給你m個數,讓你求一個最小的數,這個數是n的倍數,並且由題目中提供的m個數組成。用BFS。
此題可以用同餘判斷的方法來剪枝。
假如 A%X == B%X (設A<B)
那麼 (A*10+Ki)%X==(B*10+Ki)%X
所以A,B之中我們只要取前面的A就行,因為題目要取最小的數,通過同餘我們可以知道,A和B這兩個數在末尾添加任何相同的數MOD X之後的餘數都是一樣的,因此對於比A大的數我們就沒有必要去擴充了。B可以直接減掉。即對餘數進行標記,已經出現過的餘數(即當前得到的數與我之前已經得到的某個數同餘),將不再擴充節點。
先對m個數字從小到大排序,這樣保證我們前面平湊得到的數字是最小的。越早搜尋到的符合題目要求的就是我們要的最小的數。
Multiple
| Time Limit: 1000MS |
|
Memory Limit: 32768K |
| Total Submissions: 5394 |
|
Accepted: 1174 |
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
223701211
Sample Output
1100
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct node{ int mod,dig,pt;}queue[500];int flag[5010],a[100];int front,rear;int m,n;void output(int p){ if(queue[p].pt==-1) return; output(queue[p].pt); printf("%d",queue[p].dig);}void bfs(){ memset(flag,0,sizeof(flag)); front=rear=0; queue[rear].mod=0; queue[rear].dig=0; queue[rear].pt=-1; rear++; while(front<rear) { node tmp; tmp=queue[front]; for(int i=0;i<n;i++) { if(!flag[(tmp.mod*10+a[i])%m] && (tmp.pt!=-1 || a[i]>0)) { queue[rear].mod=(tmp.mod*10+a[i])%m; queue[rear].dig=a[i]; queue[rear].pt=front; flag[queue[rear].mod]=1; if(queue[rear].mod==0) { output(rear); printf("\n"); return ; } rear++; } } front++; } printf("0\n");}int main(){ while(~scanf("%d",&m)) { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n); if(m==0) printf("0\n"); else bfs(); }}