HDU 4474:Yet Another Multiple Problem

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值