HDU 1664 BFS

HDU 1664

题目链接:

题意:

给一个数字n,一个数字,在满足数字每个位上拥有最少不同数字的前提下,该数字的最小值。

思路:

想到了在n的范围内,如果出现重复数就不在往下走的做法。但是依然有难处理的地方,就是如何保证不同数字最少。也想过对n个、十、百、千等每位分解出来讨论,然后维护一个区间,讨论0123456789的区间。

然而最后都会卡在这个数到底有多长的条件下。

题解是用前向星来存,如果余数出现过就跳过的方法。剩下的实现方法都是可以自己做的。

值得注意的是string标准库的用法。

string str

初始化 str = “” / str = string(“***”) / str - string(char a, int len)

连接 str += ‘*’

翻转 reverse(str.begin(), str.end())

输出 可以用数组循环的遍历方式输出%c,或者cout

但是不能print(“%s”, str)

源码:

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <cmath>

#include <algorithm>

#include <iostream>

#include <queue>

#include <string>

using namespace std;

const int MAXN = 70000;

int n, anscnt;

int da[5];

string ans, curans;

struct Lv

{

    int pre, val, cnt, d;

    Lv(){}

    Lv(int _pre, int _val, int _cnt, int _d){pre = _pre, val = _val, cnt = _cnt; d = _d;}

}que[MAXN];

int vis[MAXN];

bool BFS(int k)

{

    memset(vis, 0, sizeof(vis));

    int st, en;

    st = en = 0;

    que[en++] = Lv(-1, 0, 0, 0);

    while(st < en){

        Lv org = que[st++];

        for(int i = 0 ; i < k ; i++){

            int tval = (org.val * 10 + da[i]) % n;

            if(vis[tval] || (st == 1 && da[i] == 0))

                continue;

            vis[tval] = 1;

            if(tval == 0){

                curans = "";

                curans += da[i] + '0';

                while(org.pre != -1){

                    curans += org.d + '0';

                    org = que[org.pre];

                }

                reverse(curans.begin(), curans.end());

                return 1;

            }

            que[en++] = Lv(st-1, tval, org.cnt + 1, da[i]);

        }

    }

    return 0;

}

int main()

{

    while(scanf("%d", &n) != EOF && n){

        ans = "";

        anscnt = MAXN;

        for(da[0] = 1 ; da[0] <= 9 ; da[0]++){

            if(BFS(1)){

                if(anscnt > (int)curans.size()){

                    anscnt = curans.size();

                    ans = curans;

                }

            }

        }

        if(anscnt == MAXN){

            for(da[0] = 0 ; da[0] <= 9 ; da[0]++){

                for(da[1] = da[0] + 1 ; da[1] <= 9 ; da[1]++){

                    if(BFS(2)){

                        if(anscnt > (int)curans.size()){

                            anscnt = curans.size();

                            ans = curans;

                        }

                        else if(anscnt == (int)curans.size() && ans > curans)

                            ans = curans;

                    }

                }

            }

        }

        cout << ans << endl;

    }

    return 0;

}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值