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

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

猜你喜欢

转载自blog.csdn.net/qq_37451344/article/details/82493435
今日推荐