HDU4474 Yet Another Multiple Problem

Yet Another Multiple Problem


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


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


Source
2012 Asia Chengdu Regional Contest


题意:给出一个n和m,然后后面给m个数,求出一串数字是n的倍数(要求最小),并且这串数字不能出现给出的m个数。

分析:这次是长见识了,这题居然是用BFS做,将一个数字加到我们求的串后面判断能不能被n整除,这里有个优化也是保证最小的条件就是如果这个余数在前面出现过了就不要再往这个数后面加数字了(两个数的余数相同),因为前面出现过的已经往后加了而且前面出现的数字肯定比现在出现的小(数字可能很大,用字符保存)。。最后dfs打印路径就行。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=1000010;
struct node
{
    int pre,mod;
    char c;
}q[MAXN];
bool v[10010];
void dfs(int cur)
{
    if(cur==0)
        return;
    dfs(q[cur].pre);
    printf("%c",q[cur].c);
}
int main()
{
    int a[10],n,m,i,j,l,r,x,flag=1;
    bool vis[10];
    while(scanf("%d%d",&n,&m)==2)
    {
        memset(vis,0,sizeof(vis));
        for(i=0;i<m;i++)
        {
            scanf("%d",&x);
            vis[x]=1;
        }
        m=0;
        for(i=0;i<10;i++)
        {
            if(!vis[i])
            {
                a[m++]=i;
            }
        }
        printf("Case %d: ",flag++);
        if(m==0)
        {
            printf("-1\n");
            continue;
        }
        memset(v,0,sizeof(v));
        l=1,r=1;
        int ans=-1;
        for(i=0;i<m;i++)
        {
            if(a[i])
            {
                q[r].pre=0;
                v[q[r].mod=a[i]%n]=1;
                q[r].c=a[i]+'0';
                if(q[r].mod==0)
                {
                    ans=r;
                    break;
                }
                r++;
            }
        }
        while(l<r&&ans==-1)
        {
            for(i=0;i<m;i++)
            {
                q[r].mod=(q[l].mod*10+a[i])%n;
                if(!v[q[r].mod])
                {
                    v[q[r].mod]=1;
                    q[r].pre=l;
                    q[r].c=a[i]+'0';
                    if(q[r].mod==0)
                    {
                        ans=r;
                        break;
                    }
                    r++;
                }
            }
            l++;
        }
        if(ans==-1)
            printf("-1\n");
        else
            dfs(ans),printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值