HDU 4474&&POJ 1465 BFS&&余数判重

两道题只是输入输出格式略有不同

给出n,m,m个数

要求生成一个数x,是n的倍数,并且只由这M个数构成(或不能含有这M个数中的任意一个),求最小的x,没有则输出-1(0);


BFS找每一个满足n的倍数的数,用余数判重优化

对于给定两个数A,B,如果A和B模N都相同,设为C,即:

A=x*N+C

B=y*N+C

那么如果在A后面加上一个数字能够被N整除,则在B后面加上这个数字也肯定可以被N整除

即:(A*10+X)%N==(B*10+X)%N

因此可以利用模N的结果进行判重,只保留相同余数的最小数,于是采用BFS搜索


HDU4474:

#include "stdio.h"
#include "string.h"
#include "queue"
using namespace std;

int hash[11],num[10010],pre[10010];
int n;

void pri(int k)
{
    if (pre[k]!=-1) pri(pre[k]);
    printf("%d",num[k]);
}
void bfs()
{
    queue<int>q;
    int i,cur,next;

    for (i=1;i<=9;i++)
        if(hash[i]==0)
        {
            cur=i%n;
            if (cur==0) { printf("%d\n",i); return ;}
            num[cur]=i;
            q.push(cur);
        }

    while (!q.empty())
    {
        cur=q.front();
        q.pop();
        for (i=0;i<=9;i++)
            if(hash[i]==0)
            {
                next=(cur*10+i)%n;
                if (num[next]==-1)
                {
                    q.push(next);
                    num[next]=i;
                    pre[next]=cur;
                }
                if (next==0) {pri(next); printf("\n"); return ;}
            }
    }
    printf("-1\n");
    return ;
}
int main()
{
    int m,x,Case=1;
    while (scanf("%d",&n)!=EOF)
    {
        memset(hash,0,sizeof(hash));
        memset(num,-1,sizeof(num));
        memset(pre,-1,sizeof(pre));

        scanf("%d",&m);
        while (m--)
        {
            scanf("%d",&x);
            hash[x]=1;
        }
        printf("Case %d: ",Case++);
        if(n==0) { printf("-1\n"); continue;}
        bfs();
    }
    return 0;
}

POJ1465:

#include "stdio.h"
#include "string.h"
#include "queue"
using namespace std;

int hash[11],num[10010],pre[10010];
int n;

void pri(int k)
{
    if (pre[k]!=-1) pri(pre[k]);
    printf("%d",num[k]);
}
void bfs()
{
    queue<int>q;
    int i,cur,next;

    for (i=1;i<=9;i++)
        if(hash[i]==1)
        {
            cur=i%n;
            if (cur==0) { printf("%d\n",i); return ;}
            num[cur]=i;
            q.push(cur);
        }

    while (!q.empty())
    {
        cur=q.front();
        q.pop();
        for (i=0;i<=9;i++)
            if(hash[i]==1)
            {
                next=(cur*10+i)%n;
                if (num[next]==-1)
                {
                    q.push(next);
                    num[next]=i;
                    pre[next]=cur;
                }
                if (next==0) {pri(next); printf("\n"); return ;}
            }
    }
    printf("0\n");
    return ;
}
int main()
{
    int m,x,Case=1;
    while (scanf("%d",&n)!=EOF)
    {
        memset(hash,0,sizeof(hash));
        memset(num,-1,sizeof(num));
        memset(pre,-1,sizeof(pre));

        scanf("%d",&m);
        while (m--)
        {
            scanf("%d",&x);
            hash[x]=1;
        }
      //  printf("Case %d: ",Case++);
        if(n==0) { printf("0\n"); continue;}
        bfs();
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值