目录:
题目:
题意:
在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;
}