题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4474
Time Limit: 40000/20000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description

There are tons of problems about integer multiples. Despite the fact that the topic is not original, the content is highly challenging. That’s why we call it “Yet Another Multiple Problem”.
In this problem, you’re asked to solve the following question: Given a positive integer n and m decimal digits, what is the minimal positive multiple of n whose decimal notation does not contain any of the given digits?

Input

There are several test cases.
For each test case, there are two lines. The first line contains two integers n and m (1 ≤ n ≤ 104). The second line contains m decimal digits separated by spaces.
Input is terminated by EOF.

Output

For each test case, output one line “Case X: Y” where X is the test case number (starting from 1) while Y is the minimal multiple satisfying the above-mentioned conditions or “-1” (without quotation marks) in case there does not exist such a multiple.

Sample Input

2345 3
7 8 9
100 1
0

Sample Output

Case 1: 2345
Case 2: -1

Problem solving report:

Description: 给你n,m和输入m个数,问n的最小倍数且不含这m个数的是多少。
Problem solving: BFS搜索,利用同余模定理优化。
同余模定理:对于大数求余,超出long long后直接用%是不行的。但是有这样的定理:
(a+b)%c = (a%c + b%c)%c; (a*b)%c = (a%c * b%c)%c。所以对于大数,我们就有(x*n+d)%n求法

Accepted Code:

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e4 + 5;
bool vis[15];
int pre[MAXN], vist[MAXN];
void print(int s) {//输出
    if (~pre[s])
        print(pre[s]);
    printf("%d", vist[s]);
}
void BFS(int n) {
    queue <int> Q;
    for (int i = 1; i < 10; i++) {
        if (!vis[i] && !~vist[i % n]) {//m里面没有i,且i%n的余数也没出现
            Q.push(i % n);
            vist[i % n] = i;
        }
    }
    while (!Q.empty()) {
        int u = Q.front();
        Q.pop();
        if (!u) {//余数为0代表就是n的倍数
            print(u);
            printf("\n");
            return ;
        }
        for (int i = 0; i < 10; i++) {
            if (!vis[i]) {
                int v = ((u << 1) + (u << 3) + i) % n;
                if (!~vist[v]) {
                    vist[v] = i;//记录余数是哪位得的
                    pre[v] = u;//记录路径,便于输出
                    Q.push(v);
                }
            }
        }
    }
    printf("-1\n");
}
int main() {
    int n, m, a, kase = 0;
    
    while (~scanf("%d%d", &n, &m)) {
        memset(pre, -1, sizeof(pre));
        memset(vist, -1, sizeof(vist));
        memset(vis, false, sizeof(vis));
        while (m--) {
            scanf("%d", &a);
            vis[a] = true;
        }
        printf("Case %d: ", ++kase);
        BFS(n);
    }
    return 0;
}