HDU 4474

参考http://blog.163.com/judith_my_room/blog/static/23746401620149241014830/

题意:给定几个不能用的数字,让用其他数字组成一个n的最小倍数,不能则结果为-1

题解:想了半天没想出来,枚举n的倍数一看数据范围就要哭了;最后只好搜题解,看到大神们都说BFS,然后就自己用自以为正确的(最大100000倍)水了一发,死在15ms,感觉是自己想错了,但想到那么长的结果怎么存,又不知所措,只好再去翻,终于发现了通俗易懂的题解——bfs搜所有可以到达的余数,如果重复则-1,如果最后到达0则找到结果,刚开始余数肯定是逐渐增大的,后面每次加一位,队首的肯定是最小的结果,无需优先队列,TAT。看了一遍终于懂了,然后开始自己写,交了一发RE,回去发现取模与存结果顺序弄反了,数组刚好卡那么大。改了一发,终于AC。返回Vjudge又提交一发结果CE,瞬间懵逼。然后发现是编译器问题,c++过不了,各种百度之后,终于发现原来是c的string.h和c++的string有区别,改掉之后终于又AC了。

#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
#include <vector>
#include <algorithm>
#include <cassert>
#include <queue>
#include <deque>
#include <cstdlib>
#include <set>
#include <map>
#define PB push_back
#define MP make_pair

using namespace std;
const int maxn=1e5+7;

int num[15];
int dig[15];
int dn;
bool visit[maxn];

void bfs(int n)
{
    struct node
    {
        int mod;
        string s;
    }w;
    queue<node> q;
    w.mod=0;
    w.s="";
    q.push(w);
    while(!q.empty()){
        w=q.front();
        //cout<<w.s<<' ';
        q.pop();
        node e;
        for(int i=0;i<dn;i++){
            e=w;
            int tmp=w.mod*10+dig[i];
            //cout<<tmp<<' ';
            if(tmp==0) continue;
            e.mod=tmp%n;
            e.s+=(dig[i]+'0');
            tmp%=n;
            if(!visit[tmp]){
                visit[tmp]=1;
                if(tmp==0){
                    //printf("%s\n",e.s);
                    cout<< e.s <<endl;
                    return;
                }
                //cout<<e.s<<' ';
                q.push(e);
            }
        }
    }
    cout<<-1<<endl;
    return ;
}
int main() {
    int n,m,x,cas=1;
    while(cin>>n>>m){
        memset(num, 0, sizeof num);
        memset(visit, 0, sizeof visit);
        for(int i=0;i<m;i++){
            //scanf("%d",&x);
            cin>>x;
            num[x]=1;
        }
        dn=0;
        for(int i=0;i<10;i++){
            if(!num[i]) dig[dn++]=i;
        }//cout<<dn<<' ';
        //printf("Case %d: ",cas++);
        cout<<"Case "<<cas++<<": ";
        bfs(n);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值