https://www.luogu.org/problemnew/show/P2602
题目描述
给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。
输入输出格式
输入格式:
输入文件中仅包含一行两个整数a、b,含义如上所述。
输出格式:
输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。
输入输出样例
输入样例#1: 复制
1 99
输出样例#1: 复制
9 20 20 20 20 20 20 20 20 20
说明
30%的数据中,a<=b<=10^6;
100%的数据中,a<=b<=10^12。
啊啊啊啊,离联赛只差没几天的,菜鸡仍然在RE边缘徘徊,诶,太惨了
菜鸡在这儿立志要学习DFS版的,否则尽情来喷我吧,骂不还口
求解的时候没有考虑原来的数本身的数字,就吊死在题头
#include<cstdio>
#define ll long long
using namespace std;
ll l,r;
const int N=20;
struct A
{
ll f[N][N][N];
int a[N];
inline void pre()
{
for(int i=0;i<=9;i++) f[1][i][i]=1;
for(int i=2;i<=13;i++)
for(int j=0;j<=9;j++)
{
ll num=1;
for(int ii=1;ii<i;ii++) num*=10;
f[i][j][j]+=num;
for(int k=0;k<=9;k++)
for(int l=0;l<=9;l++) f[i][j][l]+=f[i-1][k][l];
}
}
ll sum(ll x,int bj)
{
int len=0; ll ret=0;
while(x) a[++len]=x%10,x/=10;
for(int i=1;i<len;i++)
for(int j=1;j<=9;j++) ret+=f[i][j][bj];
for(int i=1;i<a[len];i++) ret+=f[len][i][bj];
int num0=0;
if(a[len]==bj) num0++;
for(int i=len-1;i;i--)
{
ll num=1;
for(int k=i-1;k;k--) num*=10;
for(int j=0;j<a[i];j++)
ret+=f[i][j][bj]+num*num0;
if(a[i]==bj) num0++;
}
return ret;
}
}DP;
int main()
{
DP.pre();
scanf("%lld%lld",&l,&r);
for(int i=0;i<=9;i++)
printf("%lld%c",DP.sum(r+1,i)-DP.sum(l,i),(i==9)?'\n':' ');
return 0;
}
洛谷P2602数字出现次数解析
本文详细解析洛谷P2602题目,探讨如何计算指定范围内所有整数中每个数字出现的频率。通过深度优先搜索(DFS)的方法,使用C++实现并分享代码细节。
537

被折叠的 条评论
为什么被折叠?



