校招模拟 [编程题]页码统计

来源:互联网 发布:大连育知同创怎么样 编辑:程序博客网 时间:2024/05/17 13:43
链接:https://www.nowcoder.com/questionTerminal/3a003cb6a3174ef9835fa603e01d8b52
来源:牛客网

牛牛新买了一本算法书,算法书一共有n页,页码从1到n。牛牛于是想了一个算法题目:在这本算法书页码中0~9每个数字分别出现了多少次?
输入描述:
输入包括一个整数n(1 ≤ n ≤ 1,000,000,000)


输出描述:
输出包括一行10个整数,即0~9这些数字在页码中出现的次数,以空格分隔。行末无空格。

输入例子:
999

输出例子:
189 300 300 300 300 300 300 300 300 300
数位DP:
/*************************************************************************> File Name: b.cpp> Author:ywdxz > Mail: > Created Time: 2017年03月07日 星期二 20时21分09秒************************************************************************/#include<iostream>#include<cstdio>#include<cmath>using namespace std;int dp[20][20][15];//dp[i][j][l]:长度为i以j开头l出现的次数int diget[20];//放置m的各个位数int H[20];int F[20];//统计0至9出现的次数 void init()  //预处理{    for(int i=0;i<=9;i++)        dp[1][i][i]=1;    for(int i=2;i<=10;i++)        for(int j=0;j<=9;j++)        {            dp[i][j][j]=pow(10,i-1);            for(int l=0;l<=9;l++)                for(int k=0;k<=9;k++)                    dp[i][j][l]+=dp[i-1][k][l];        }}void sovle(int n){    init();    int T=0;    while(n>0)//从低位到高位放置n的各个位上的数到diget[]中    {        diget[++T]=n%10;        n/=10;    }    for(int i=T;i>0;i--)//从高位开始统计    {           int ant=0;        for(int j=0;j<(i==1?diget[i]+1:diget[i]);j++)//最低位循环条件为<=;        {            H[i+1]+=pow(10,i-1);//i+1位确定后,i位至最低位的变化次数            for(int l=0;l<=9;l++)//统计0至9                if(i==T&&j==0&&l==0)//最高位以0开头,0的出现次数(排除前导0的出现次数)                {                    //:长度从次高位到最低位,以1到9开头,0出现的次数                    for(int I=T-1;I>0;I--)                        for(int J=1;J<=9;J++)                            F[l]+=dp[I][J][l];                }                else                    F[l]+=dp[i][j][l];//最高不以0开头就不存在前导0,所以直接加        }    }    for(int i=T;i>1;i--)  //确定的高位在后续变化中各个位上数的出现的次数        for(int j=T;j>=i;j--)           F[diget[j]]+=H[i];}int main(){    int m;    cin>>m;    sovle(m);    for(int i=0;i<9;i++)    cout<<F[i]<<" ";    cout<<F[9]<<endl;}
补充(其他方法):
#include <cstdio>#include <iostream>#include <string>#include <algorithm>#include <cstring>using namespace std;long long F[11],n;void Fun(int k){int a=n/k;int b=n%k;{//0 单独考虑(考虑前导0的情况)if(a/10>0){if(a%10>0){F[0]+=(a/10)*k;}else{F[0]+=(a/10-1)*k+b+1;}}}for(int i=1;i<10;i++){// 1-9 的情况 if(a%10>i){F[i]+=(a/10+1)*k;}else if(a%10==i){F[i]+=(a/10)*k+b+1;}else{F[i]+=(a/10)*k;}}}int main(){while(scanf("%d",&n)!=EOF){memset(F,0,sizeof(F));for(int i=1;i<=n;i*=10){Fun(i);}for(int i=0;i<9;i++){printf("%d ",F[i]);}printf("%lld\n",F[9]);}return 0;}


0 0
原创粉丝点击