Time Limit: 1000MS | Memory Limit: 32768K | |
Total Submissions: 7211 | Accepted: 1545 |
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.
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:
An example of input and output:
Sample Input
22 3 7 0 1 2 1 1
Sample Output
110 0
余数判重
A=a*N +e 即A%N =e
B= b*N+e即B%N=e
当A B mod N的余数相同时,如果先出现A 。在A 后加上一个数 i 时 , 新的数 C = 10 *a*N + 10 *e+i;
同样 B后加上数 i 时 , D = 10*b*N +10*e+i; 由于C D 前边 10*a*N 和 10*b*N 都是N的倍数 ,则C D mod N 的余数都是有 10*e+i 决定的。
于是 C D mod N 同余。
因此 A B 同余 都添加上 i 之后 新的两个数C D也是同余的。在无论添加多少个数,新生成的两个数也是同余的。因此 在A 之后如果不出现 N的倍数 ,则
在B之后也不会出现。 在A 之后出现,那B之后也会出现。 有因为要求求最小值。所以只需要搜索min(A,B)之后的 ,对于另外一个数之后就不用搜索了。
因为对M个排序后,先填入的是小的值,所以 A B 先出现的值小。所以后出现的同余的数 就不用搜索了。。
因此可以余数判重后剪枝。。。。
#include<iostream> #include<string.h> #include<stdio.h> #include<queue> #include<algorithm> #include<stdlib.h> using namespace std; struct node { int pre,r,digit; }; node qu[5500]; int n,m,a[5500]; int vis[5500]; void print(int head)//输出 { if(head==-1)return; print(qu[head].pre); printf("%d",qu[head].digit); } void bfs() { if(!n)//n为0输出0并返回 { cout<<0<<endl; return; } memset(vis,0,sizeof(vis));//用来标记余数 int rear,front; front=rear=0; for(int i=1;i<=m;i++) { if(a[i]==0) continue; node p; p.digit=a[i];p.pre=-1;p.r=a[i]%n; qu[rear++]=p; } while(front<rear) { node p=qu[front]; node q; if(p.r==0) { print(front); puts(""); return; } for(int i=1;i<=m;i++) { q.digit=a[i]; q.pre=front; q.r=(p.r*10+a[i])%n; if(!vis[q.r]) { qu[rear++]=q; vis[q.r]=1; } } front++; } puts("0"); return; } bool cmp(int a,int b) { return a<b; } int main() { while(~scanf("%d",&n)) { scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d",&a[i]); } sort(a+1,a+1+m,cmp); bfs(); } return 0; }