当前位置: 代码迷 >> 综合 >> UVA 1569 Multiple (最短路+同余性质约束)
  详细解决方案

UVA 1569 Multiple (最短路+同余性质约束)

热度:29   发布时间:2023-11-15 16:05:55.0

题目链接: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;
}

 

 

  相关解决方案