题意:给一个数n,和m个0~9的数字,问n或者n的倍数能不能只由这m个数字组成,能的话输出最小的那个,不能输出0.
解法:BFS搜之。但是单纯的暴力肯定不行,因为你不能判断不能组成的情况。
由 (a*x+b)%n == ((a%n)*x+b)%n 可知,当两个数对n取模的值相同时,对较大的那个数的搜索必然是重复的,可以跳过。
然后就是题目的另外一个坑,题目给的m个数必然是在0~9之间,但是m可能远大于10..直接存数组里的结果不是超时就是RE,所以这里需要判重。
解法:BFS搜之。但是单纯的暴力肯定不行,因为你不能判断不能组成的情况。
由 (a*x+b)%n == ((a%n)*x+b)%n 可知,当两个数对n取模的值相同时,对较大的那个数的搜索必然是重复的,可以跳过。
然后就是题目的另外一个坑,题目给的m个数必然是在0~9之间,但是m可能远大于10..直接存数组里的结果不是超时就是RE,所以这里需要判重。
RE一地MLE一地,活生生的血与泪啊
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define clr(a,b) memset((a),(b),sizeof(a))
const int INF = ~0u>>1;
int c[15];
int n,m;
int hash[5010];
struct Q{
int ep,mod,num;
}q[2000000],f,e;
int ans[2000000];
void Print(int pos)
{
int p = 0;
while(pos > 0)
{
ans[p++] = q[pos].num;
pos = q[pos].ep;
}
for(int i=p-1; i>=0; i--) printf("%d", ans[i]);
printf("\n");
}
int bfs()
{
int head, tail, i;
head = tail = 0;
q[0].mod = 0;
while(head <= tail)
{
f = q[head ++];
for(i=0; i<m; i++)
{
e.mod = (f.mod*10+c[i])%n;
e.ep = head - 1;
e.num = c[i];
if(f.mod == 0 && c[i] == 0) continue;
if(hash[e.mod]) continue;
q[++tail] = e;
if(e.mod == 0) { Print(tail); return 1; }
hash[e.mod] = 1;
}
}
return 0;
}
int main()
{
int i;
int d;
while(~scanf("%d%d", &n, &m))
{
clr(hash,0);
for(i=0; i<15; i++) c[i] = INF;
for(i=0; i<m; i++)
{
scanf("%d", &d);
c[d] = d;
}
sort(c,c+15);
if(n == 0)
{
printf("0\n");
}
else
{
if(bfs() == 0) printf("0\n");
}
}
return 0;
}