题目描述
一本书的页数为N,页码从1开始编起,请你求出全部页码中,用了多少个0,1,2,…,9。其中—个页码不含多余的0,如N=1234时第5页不是0005,只是5。
输入格式
一个正整数N(N≤10^9),表示总的页码。
输出格式
共十行:第k行为数字k-1的个数。
DP[i][j][k]表示长度为i以j为开头的数字有多少个数字k
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
#define int long long
const int maxn=15;
int dp[maxn][maxn][maxn],sum[maxn][maxn];
int res[maxn];
void DP(int num)
{
vector<int> v;
int cp=num;
while(num)
{
v.push_back(num%10);
num/=10;
}
int t=v.size();
for(int i=t-1;i>=0;i--) {
int x = v[i];
res[x]++;
int MOD=pow(10,i);
if(x>=1) {
if (i == t - 1) {
for (int j = 0; j <= 9; j++) {
res[j] += sum[i][j];
}
//cout<<res[0]<<endl;
} else {
for (int j = 0; j <= 9; j++) {
for (int k = 0; k <= 9; k++) {
res[k] += dp[i][j][k];
}
}
}
}
res[v[i]]+=cp%MOD;
//cout<<cp%MOD<<endl;
for(int j=1;j<v[i];j++) {
for (int k = 0; k <= 9; k++) {
res[k] += dp[i + 1][j][k];
}
}
if(i!=t-1&&x!=0) res[0]+=MOD;
}
}
signed main()
{
int num=1;
for(int i=0;i<=9;i++) dp[1][i][i]=1,sum[1][i]=1;
//sum[1][0]--;
for(int i=2;i<=9;i++)
{
num*=10;
for(int k=0;k<=9;k++)
{
sum[i][k]+=sum[i-1][k];
for(int j=0;j<=9;j++)
{
if(j==k) dp[i][j][k]+=num;
for(int t=0;t<=9;t++)
dp[i][j][k]+=dp[i-1][t][k];
if(j!=0)
{
sum[i][k]+=dp[i][j][k];
}
}
}
}
int n;cin>>n;
DP(n);
if(res[0]>0) res[0]--;
for(int i=0;i<=9;i++)
{
cout<<res[i]<<endl;
}
}
这篇博客介绍了一个用于计算书籍页码中每个数字出现次数的算法。通过动态规划的方法,该程序可以有效地计算从1到指定页码N(N≤10^9)中,0到9各数字的使用频率。代码使用C++编写,实现了DP[i][j][k]表示长度为i以j为开头的数字有多少个数字k,并输出了每种数字的个数。
1559

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



