12年成都现场赛K_Yet Another Multiple Problem

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

题目大意:

给一个正整数N(N<10^4),和M个0~9的数字,要求求出N的最小整数倍,这个数不包含给出的M个数字,不存在输出-1。比如,N=1,M=1 给出的一个数是1  那么输出就是2 。

解题思路:

用所有能有的数字去组合新的数字,直到队列空或者找到答案,而对于每个数来说,如果不是N的整数倍,那么对N取余一定是1~N-1的数字,而对于一个对N取模为K的数字,那么这个数再加上N取模依然为K,所以我们找到的第一个肯定是最优解,所以用这个作为数字入队的条件。一看N只有10^4,所以用数组满可以的。队列扩展的时候保证按从小到大的顺序,那么组合出来的数字也是递增的,符合题目要求,具体看代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<utility>
#define INF (1<<30)
#define EPS 1e-6
#define PI acos(-1)
#define lowbit(x) ((x) & (-(x)))
#define IDX(l,r) ((l)+(r) | (l)!=(r))
#define ABS(x) ((x)>0?(x):-(x))
#define SET(a,b) memset(a,b,sizeof(a))
#define NN 40
#define MM 10010
inline long long ReadInt()
{
    char ch = getchar();
    long long data = 0;
    while (ch < '0' || ch > '9')
        ch = getchar();
    do
    {
        data = data * 10 + ch - '0';
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9');
    return data;
}
using namespace std;

bool mod[100001];
int a[10];
int n, m, cnt;
struct node
{
    int val;
    int f;
    int sec;

} q[1000000];
void output (int t)
{
    if (q[t].f != -1) output (q[t].f);
    printf ("%d", q[t].sec);
}
void  bfs()
{
    int h = 1, t = 0;
    q[t].val = 0;
    for (int i = 1; i <= 9; i++) if (a[i] == 0)
        {
            if (i%n==0)
            {
                printf("%d\n",i);
                return;
            }
            t++;
            q[t].val = i;
            q[t].sec = i;
            q[t].f = -1;
        }
    if (t == 0)
    {
        printf ("-1\n");
        return;
    }
    while (h <= t)
    {
        for (int i = 0; i <= 9; i++)
        {
            if (a[i] == 0)
            {
                int temp = q[h].val;
                temp = (temp * 10 + i) % n;
                if (temp == 0)
                {
                    t++;
                    q[t].f = h;
                    q[t].sec = i;
                    output (t);
                    printf ("\n");
                    return;
                }
                if (mod[temp] == false)
                {
                    t++;
                    q[t].f = h;
                    q[t].val = temp;
                    q[t].sec = i;
                    mod[temp] = true;
                    cnt++;
                }
                else
                    continue;
            }
        }
        h++;
    }
    printf ("-1\n");
}
int main()
{
    int cas = 1;
    while (~scanf ("%d%d", &n, &m))
    {
        int temp;
        SET (a, 0);
        SET (mod, 0);
        for (int i = 1; i <= m; i++)
        {
            scanf ("%d", &temp);
            a[temp] = 1;
        }
        printf ("Case %d: ", cas++);
        bfs();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值