题目链接:https://cn.vjudge.net/problem/UVA-1569
#include<bits/stdc++.h>
#pragma comment(linker,"/STACK:1024000000,1024000000")
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define read(x,y) scanf("%d%d",&x,&y)
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define ll long long
const int maxn =1e4+5;
const int mod=1e9+7;
ll powmod(ll x,ll y) {ll t;for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod;return t;}
ll gcd(ll x,ll y) { return y==0?x:gcd(y,x%y); }
int n,m,x[maxn];
/*
题目大意:很明显,就是最短路搜索出来一个最小的符合要求的数字。
有几个问题,数字可能爆范围,
那么按位存储到容器里里。
如何进行答案的转移呢?
类比一维数组,就是容器的复制外加额外添加即可,
根据同余性质,如果一个同余位已经被走过 就没必要再走了,
因为每次都面临相同的数据集合的选择。
如何保证答案最小,只要刚开始排序就行了,
不能用优先队列,用了会WA,
因为队列里存储的是取余后的值,
其路径大小不能以这个标识来扩充约束,
刚开始从小到大,根据队列的性质,最后取出来的也是
有序的(不是余数大小)
代码写的挫,且路子不正,下面附一份大神的代码
*/
vector<int> vis[maxn];///乍一这样写,代码比较挫....
queue<int> q;///不能用优先队列.
int bfs()
{
while(!q.empty())
{
int tp=q.front(); q.pop();
if(tp%n==0) return 1;
for(int i=0;i<m;i++)
{
int v=(tp*10+x[i])%n;
if(vis[v].size()) continue;
vis[v]=vis[tp]; vis[v].insert(vis[v].begin(),x[i]);
q.push(v);
}
}
return 0;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
while(!q.empty()) q.pop();
for(int i=0;i<maxn;i++) vis[i].clear();
scanf("%d",&m);for(int i=0;i<m;i++) scanf("%d",&x[i]);
sort(x,x+m);
for(int i=0;i<m;i++)
{
///同余的就不用再加入了
if(x[i]&&n)
{
int tmp=x[i]%n;
if(vis[tmp].size()) continue;
q.push(x[i]); int tp=x[i];
while(x[i])
{
vis[tmp].push_back(x[i]%10);
x[i] /= 10;
}
x[i]=tp;
}
}
int mark=bfs();
if(n==0||mark==0) puts("0");
else
{
for(int i=vis[0].size()-1;i>=0;i--) printf("%d",vis[0][i]); puts("");
}
}
return 0;
}
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 5005;
const int inf = 0x3f3f3f3f;
int N, M, A[maxn], D[maxn], P[maxn], W[maxn];
void put (int u) {
if (u == 0) return;
put(P[u]);
printf("%d", W[u]);
}
bool bfs () {
queue<int> que;
memset(D, 0, sizeof(D));
for (int i = 0; i < M; i++) {
if (A[i] == 0) continue;
int t = A[i] % N;
P[t] = 0, W[t] = A[i], D[t] = 1;
que.push(t);
}
while (!que.empty()) {
int u = que.front();
que.pop();
if (u == 0) {
put(P[u]);
printf("%d\n", W[u]);
return true;
}
for (int i = 0; i < M; i++) {
int v = (u * 10 + A[i]) % N;
if (!D[v]) {
D[v] = 1;
W[v] = A[i];
P[v] = u;
que.push(v);
}
}
}
return false;
}
int main () {
while (scanf("%d", &N) == 1) {
scanf("%d", &M);
int x;
memset(A, 0, sizeof(A));
for (int i = 0; i < M; i++)
scanf("%d", &A[i]);
sort(A, A + M);
if (N == 0 || !bfs())
printf("0\n");
}
return 0;
}