Poj 1465 Multiple BFS+余数判重

题意:现在给你M个数字和另外一个数N(N<5000),问你能否用这M个数字中的一个或几个(可以重复)来构成一个数,使得这个数能被N整除,如果能输出最小的,不能输出0

显然可以将构成的数字位数作为层数来进行bfs,通过对给你的M个数进行排序,来保证最先出现的肯定是最小的。

关键问题是如何判重?

因为有两个数要是被N除之后余数相等,那么在这两个数后面添加相同个数字之后余数也必定相等

A = a*N+C

B = b*N+C

(A*10+k)%N = C*10+k%N=(B*10+k)%N

所以每个数作为前缀的时候一样的余数的只需要出现一次即可,就可以判重了。

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <cstring>
#include <string>


using namespace std;

int N,M,num[1000];
int val[5555],pre[5555];
int len[5555],res[5555];
bool tab[5555];

bool notzero(int id) {
    return !(len[id] == 1 && val[id] == 0);
}

void print_path(int now) {
    if(~pre[now]) print_path(pre[now]);
    putchar(val[now] + '0');
}

int main() {
    while(scanf("%d%d",&N,&M) != EOF) {
        memset(tab,0,sizeof(tab));
        for(int i = 0;i < M;i++) {
            scanf("%d",&num[i]);
        }
        sort(num,num + M);
        if(N == 0) {
            puts("0"); continue;
        }
        int front = 0,rear = 0;
        for(int i = 0;i < M;i++) {
            len[rear] = 1;
            res[rear] = num[i] % N;
            pre[rear] = -1;
            val[rear] = num[i];
            rear++;
            if(num[i] != 0) {
                tab[num[i] % N] = true;
            }
        }
        int ans = 0;
        while(front < rear) {
            int now = front; front++; 
            if(res[now] == 0 && notzero(now)) {
                ans = now; break;
            }           
            for(int i = 0;i < M;i++) {
                if(!notzero(now) && num[i] == 0) continue;
                int nres = (res[now] * 10 % N + num[i] % N) % N;
                if(tab[nres] == false) {
                    tab[nres] = true;
                    len[rear] = len[now] + 1;
                    res[rear] = nres;
                    pre[rear] = now;
                    val[rear] = num[i];
                    rear++;
                }
            }
        }
        if(ans == 0) puts("0");
        else {
            print_path(ans);
            putchar('
');
        }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/rolight/p/3824090.html