回 帖 发 新 帖 刷新版面

主题:[原创]页码数字统计问题及求解

问题:设一本书有n页,页码为1,2,3,4,5……n,现要统计所有页码中出现数字0,1,2……8,9出现的次数。

求解过程:先将n个页码分成0-9,10-99,100-999……10^log(10)-n几个阶段,再分别统计。
         由于数字0不能出现在页码的首位给统计带来了一定的麻烦,所以统计时用所有数字总和减去其他数字的总和。

代码实现如下:



#include<iostream>

using namespace std;
int num[10];

void sovle(int n);
void print();
void init();

void sovle(int n){
    int a,b,c,d;
    int k=1;
    for(int i=10;;i*=10){
        if(n>=i){
            for(int j=1;j<10;j++)
                num[j]+=i/10+num[j]*9;
            num[0]+=9*i/10*k;
            k++;
        }
        else{
            a=n/1000;   b=n/100%10;
            c=n/10%10;  d=n%10;
            for(int j=1;j<10;j++){
                num[j]+=1000*(a>j)+(n%1000+1)*(a==j)
                    +(a>0)*(a-1)*100+(b>j)*100+(b==j)*(n%100+1)
                    +(a==0)*(b==0)*( (c>j)*10+(c==j)*(n%10+1) )
                    +(a==0)*(b!=0)*( (b-1)*10+(c>j)*10+(c==j)*(n%10+1) )
                    +(a!=0)*((10*a+b-10)*10+(c>j)*10+(c==j)*(n%10+1))
                    +(a==0)*(b==0)*(c==0)*(d>=j)+
                    (a==0)*(b==0)*(c!=0)*( (c-1)+(d>=j) )
                    +(a==0)*(b!=0)*( (10*b+c-10)+(d>=j) )
                    +(a!=0)*( (100*a+10*b+c-100)+(d>=j) );
            }
            num[0]+=(n-i/10+1)*k;
            for(j=1;j<10;j++)
                num[0]-=num[j];
            break;
        }
    }

}

void print(){
    for(int i=0;i<10;i++)
        cout<<"数字"<<i<<"的总数为 :"<<num[i]<<endl;
}

void init(){
    for(int i=0;i<10;i++)
        num[i]=0;
}

///////////////////////////////////////

测试代码:

int main(){
    int n;
    while(1){
        scanf("%d",&n);
        sovle(n);
        cout<<"计算完毕!"<<endl;
        print();
        init();
    }
    return 0;
}

回复列表 (共2个回复)

沙发

在统计阶段10^log(10)-n时是从最高位开始向低位逐步统计的

板凳

由于是用a,b,c,d分别记录n的千位,百位,十位和个位,导致了程序的局限性:只能统计页码小于10000的数字总数

改进方法:用K记录数据n的位数,用数组di[k]记录每位的数字

改进sovle(int n)的代码为:

void sovle(int n){
    int temp=n;
    int k=1;int di[10];
    for(int i=10;;i*=10){
        if(n>=i){
            for(int j=1;j<10;j++)
                num[j]+=i/10+num[j]*9;
            num[0]+=9*i/10*k;
            di[k]=temp%10;
            temp=temp/10;
            k++;
        }
        else{
            di[k]=temp%10;
            [color=FF0000][color=00FFFF][color=FF00FF][color=C0C0C0][color=FF0000][color=0000FF][color=008080][color=0000FF][color=008080][color=0000FF][color=FF0000]for(int j=1;j<10;j++){
                num[j]+=(di[k]>j)*pow(10,k-1)+(di[k]==j)*(n%(int)pow(10,k-1)+1);
            
                temp=0;
                for(int m=k-1;m>=1;m--){
                    temp=temp*10+di[m+1];
                    num[j]+=(temp-pow(10,k-m-1))*pow(10,m-1)+(di[m]>j)*pow(10,m-1)+(di[m]==j)*(n%(int)pow(10,m-1)+1);
                    
                }[/color][/color][/color][/color][/color][/color][/color][/color][/color][/color][/color]            }
            cout<<"K="<<k<<endl;
            num[0]+=(n-i/10+1)*k;
            for(j=1;j<10;j++)
                num[0]-=num[j];
            break;
        }
    }

}

我来回复

您尚未登录,请登录后再回复。点此登录或注册