Bomb

题目:点击打开链接

题意:即“不要49”

#include<stdio.h>
#include<string.h>

bool prev, flag;
int now, len;          //标记note记忆化搜索49位数
int numb[30];                     //存储数字
long long note[30][2];
long long dfs(int now, bool prev, bool flag){
    if(now == len) return 1;        //记忆化搜索
    if(flag == false){
        if(prev == true && ~note[now][1]) return note[now][1];
        if(prev == false && ~note[now][0]) return note[now][0];
    }
    int bound = 9;
    if(flag) bound = numb[now + 1];         //如果当前位数到边界下一位数范围存在约束(0~numb[now + 1])否则范围无约束(即0~9)
    long long ret = 0;
    for(int i = 0; i <= bound; i++){
        if(prev == true && i == 9) continue;            //不要49
        ret += dfs(now + 1, i == 4, flag == true && i == bound);
    }
    if(flag == false){
        if(prev == true)
            return note[now][1] = ret;
        return note[now][0] = ret;
    }
    return ret;
}

int main(){
    int k, T;
    long long na, sum, n;
    char a[30], b[30];
    scanf("%d", &T);
    while(T--){
    	scanf("%I64d", &na); 
        sprintf(a, "%I64d", na);
        n = 0;
        len = strlen(a);
        for(int i = 0; i < len; i++) numb[i + 1] = a[i] - '0';
        memset(note, -1, sizeof(note));
        n = dfs(0, false, true);                //计算0~na之间的无49的数的个数 
        sum = na - n + 1;                            //sum即1~na之间有49的数的个数
        printf("%I64d\n", sum);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值