Hdu 5676 ztr loves lucky numbers

定义幸运数字为十进制表示下只有 4 7,并且 4 7的个数一样多的数。

求不小于 n 的最小幸运数字n1018

(这是我称为数位贪心的一个题

首先显然的是一个幸运数字的位数一定是偶数

所以如果给出的 n 的位数是奇数的话,可以直接构造一个444...777作为答案

如果是偶数的话

依然是从高位到低位考虑

记录当前的位置 pos ,剩下的 4 的个数,剩下的7的个数,是否卡到下界 bnd

这样根据 n 在当前位的那个数,可以找到状态之间的转移

值得注意的是在当前位放下4之后如果返回的值为 false ,即后面没有合法的情况,则还需要尝试放下 7 ,如果放下7之后后面没有合法的情况,则直接返回 false 即可

另外在放下 4 或者7的时候要注意 4 或者7的个数是不是足够


我是代码的昏割线


#include<cstdio>
using namespace std;

#define LL long long

int arr[30];
int anser[30];

void outans(int len){
    for(int i=0;i<len/2;i++){
        printf("4");
    }
    for(int i=0;i<len/2;i++){
        printf("7");
    }
}

int lenth(LL v){
    int ret = 0;
    while(v){
        arr[ret++] = v % 10;
        v /= 10;
    }
    return ret;
}

bool ans(int pos,int ll,int lr,bool bnd){
    if(pos < 0)
        return true;
    if(!bnd){
        if(ll){
            anser[pos] = 4;
            return ans(pos-1,ll-1,lr,bnd);
        }
        else{
            anser[pos] = 7;
            return ans(pos-1,ll,lr-1,bnd);
        }
    }
    else{
        bool flag;
        if(arr[pos] < 4 && ll){
            anser[pos] = 4;
            return ans(pos-1,ll-1,lr,false);
        }
        if(arr[pos] == 4 && ll){
            anser[pos] = 4;
            flag = ans(pos-1,ll-1,lr,true);
            if(flag)
                return true;
        }
        if(lr==0)
            return false;
        if(arr[pos] < 7){
            anser[pos] = 7;
            return ans(pos-1,ll,lr-1,false);
        }
        if(arr[pos] == 7){
            anser[pos] = 7;
            return ans(pos-1,ll,lr-1,true);
        }
        return false;
    }
}

int main(){
    LL v;
    int T;
    scanf("%d",&T);
    while(T-- && ~scanf("%I64d",&v)){
        int len = lenth(v);
        if(v <= 0){
            puts("47");
            continue;
        }
        if(len % 2){
            outans(len+1);
            puts("");
        }
        else{
            if(ans(len-1,len / 2,len / 2,true)){
                for(int i=len-1;i>=0;i--){
                    printf("%d",anser[i]);
                }
            }
            else{
                outans(len+2);
            }
            puts("");
        }
    }
    return 0;
}

然而其实这个题只要把所有符合条件的幸运数都求出来,然后每次二分就好了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值