SSL 2382 K好数

29 篇文章 0 订阅

目录:

题目:

点击阅读

题意:

在n的范围以内,共有几个每个数位上的数都不大于k的数

分析:

因为题目数据较小,可以选择用暴力,当然也可以用常规做法——dp

代码(暴力):

只是简单的枚举数字,且对其每个数位进行判断

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#define LL long long
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
int ans=0;
int main()
{
    int n=read(),k=read(),tf,j;
    for(int i=1;i<=n;i++)
    {
        tf=0;
        j=i;
        while(j>0)
        {
            if(j%10>k) {tf=1;break;}
            j/=10;
        }
        if(!tf) ans++;
    }
    printf("%d",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

代码(dp):

我们可以使用数位分离法进行dp,而动态转移方程我们需要分类处理:当我们的num>k时,ans=(k+1)*f[i-1],当我们的num<=k时,ans=ans+num*f
最后输出ans-1(算了0)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#define LL long long
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
int f=1,g=1;
int main()
{
    int n=read(),k=read(),a;
    while(n)
    {
        a=n%10;n/=10;
        if(a>k) g=(k+1)*f;
        else g+=a*f;
        f*=(k+1);
    }
    printf("%d",g-1);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值