hdu 4474 数位BFS

来源:互联网 发布:孙子涵是网络歌手吗 编辑:程序博客网 时间:2024/05/21 18:41

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 37 8 9100 10

Sample Output

Case 1: 2345Case 2: -1

说实话   一开始我完全没想到用BFS去做

说句惭愧的     下面的代码和思路都是参考其他人的博客的    我只能加上我自己的理解

这里的搜索是按照数位搜索   简单说就是   从个位开始不断向  十位  百位  千位  向上搜索      =_=||   如果只是这样的话   很明显内存  时间  都会爆

这里的话    要稍微思考一下  剪个枝

对于两个数  A%N==0  B%N==0因为题意   我们要选择较小的一个     同理   如果   A%N==C   B%N==C  那么   我们也需要选择较小的一个     只要这个较小的加上C就是我们所需的答案了           (当然其实我是一位一位向上迭代出来的……

所以   整个思路就出来了      当我们当前的  数位 与一个可行的数位结合并取模    若所得结果并未出现过    就标记并加入队列    否则   直接跳过

详见注释

ac code  (事实证明  这个算法相当快  171ms

#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#include <queue>#include <cstdlib>using namespace std;const int maxn=1000005;const int inf=0x3f3f3f3f;int n,m,num[11],ans,t;bool flag[11],vis[10005];//vis 标记保存 mod是否已出现struct node{    int pre,mod;    char c;}q[maxn];void print(int x)//路径输出{    if(x==0) return ;    print(q[x].pre);    putchar(q[x].c);}void bfs(){    int l=1,r=1;                    //把每一个个位加入队列    for(int i=0;i<t;i++) if(num[i]) //个位0 是百分百符合条件的   这里要去掉    {        q[r].pre=0;        vis[q[r].mod=num[i]%n]=true;         q[r].c=num[i]+'0';        if(q[r].mod==0)        {            ans=r;            return ;        }        r++;    }    while(l<r)    {        for(int i=0;i<t;i++)        {            int tmp=q[r].mod=(q[l].mod*10+num[i])%n;//与下一位相加并取模判断            if(!vis[tmp]) //如果未出现过            {                vis[tmp]=true;                q[r].pre=l;                q[r].c=num[i]+'0';                if(q[r].mod==0)                {                    ans=r;                    return ;                }                r++;            }        }        l++;    }}int main(){    int tmp,cas=0;    while(scanf("%d %d",&n,&m)!=EOF)    {        t=0;        memset(flag,false,sizeof flag);        for(int i=0;i<m;i++)        {            scanf("%d",&tmp);            flag[tmp]=true;        }        for(int i=0;i<10;i++)            if(!flag[i]) num[t++]=i;        printf("Case %d: ",++cas);        if(t==0) {puts("-1"); continue;} //如果一个可用数位都没有    直接输出 -1        memset(vis,false,sizeof vis);        ans=-1;        bfs();        if(ans==-1) puts("-1");        else         {            print(ans);            puts("");        }    }    return 0;}

0 0
原创粉丝点击