HDU 4474:Yet Another Multiple Problem

来源:互联网 发布:探索性数据分析 pdf 编辑:程序博客网 时间:2024/05/22 16:57

Yet Another Multiple Problem

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4474
Yet Another Multiple Problem

Time Limit: 40000/20000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 5765 Accepted Submission(s): 1322

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

题目大意:

给一个数n(1

解题思路:

这道题刚开始的时候我想到的是高精度加个判断,但是发现好像然并没有什么用,后来看了一眼别人的题解,才发现原来n是小于10000的,所以完全可以暴力搜索。从高到低枚举每一位置上的数字,因为是从高到低,从小到大枚举所以可以保证在前面的一定是最优的,这个时候我们加几个判断,枚举遇到不能出现的数字就跳过,如果现在的数字对n取模后为0则可以证明他是答案。之所以为什么能够保证答案是最优的,是因为

如果一个数%N==0,那么这个数就是N的倍数。在没有找到的前提下,如果A%N==B%N,而且A < B, 那么其实我们就可以取A而不取B,因为如果在A末尾增加C可以使得AC%N==0,那么BC%N也等于0,易得:如果A和B追加数之后%N==0,那么最优条件下追加的数肯定相同。
因此我们只需要维护组合出来的数%N的值即可,如果在搜索的途中出现了相同的%N值,就可以直接忽略了,因为肯定没有前面的优秀。

代码如下:

#include <iostream>#include <cstdio>#include <queue>#include <string>#include <cstring>#include <algorithm>using namespace std;const int maxn = 10000 + 5;int n,m;int Case = 0,pre[maxn];char ans[maxn];bool M[10],vis[maxn];bool bfs(){    queue<int>Q;    Q.push(0);    while(!Q.empty())    {        int cur = Q.front();Q.pop();        for(int i = 0;i <= 9; i++)        {            if(M[i] == true || cur == 0 && i == 0)continue;            int next = (cur*10 + i)%n;            if(vis[next])continue;            ans[next] = '0' + i;            vis[next] = true;            pre[next] = cur;            Q.push(next);            if(next == 0)return true;        }    }    return false;}void print(){    string Max_ans;    int p = 0;    while(p != 0 || Max_ans.empty())    {        Max_ans += ans[p];        p = pre[p];    }    reverse(Max_ans.begin(),Max_ans.end());    cout<<"Case "<<Case<<": "<<Max_ans<<endl;}int main(){    while(~scanf("%d%d",&n,&m))    {        memset(vis,false,sizeof(vis));        memset(M,false,sizeof(M));        Case++;        while(m--)        {            int x;            scanf("%d",&x);            M[x] = true;        }        if(!bfs())printf("Case %d: -1\n",Case);        else print();    }    return 0;}
0 0