数字统计问题

一本书的页码从自然数1 开始顺序编码直到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。例如,第6 页用数字6 表示,而不是06 006 等。数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0129

编程任务:给定表示书的总页码的10 进制整数n (1≤n≤10^9) 。编程计算书的全部页码中分别用到多少次数字0129

输入: 每个输入只有1 行,给出表示书的总页码的整数n

输出: 程序运行结束时,输出有10行,在第k行输出页码中用到数字k-1 的次数,k=1210

#include  < iostream >  
#include 
< string >  
#include 
< sstream >  
#include 
< cmath >  
#include 
< vector >  
using   namespace  std; 

double  string_to_num( string  str) 
{
// 字符串转换为double 
     double  back; 
    istringstream instr(str); 
    instr
>> back; 
    
return  back; 

int  main() 

    
int  len; 
    
double  mm;  
    
int  countNum[ 10 =  { 0 }; // 保存统计结果
    vector < int >  posNum; 
    
string  pageNum; 
    cin
>> pageNum; 
    
double  num  =  string_to_num(pageNum); 
    len 
=  pageNum.size(); 
    
if ( len  <=   1  ) 
    {
// 个位数
         for ( int  i  =   1 ; i  <=   int (num); i ++
            countNum[i] 
+=   1
    } 
    
else
    { 
        
const   char *  p  =  pageNum.c_str(); 
        
for ( int  i  =   0 ; i  <  len; i ++
        { 
            
int  curPosNum  =   int * (p + i) )  -   48 ; // 当前处理位置上的数字
            mm  =  pow( 10.0 ,len - i - 2 *  (len - i - 1 ); // 由书上公式得f(n-1)=(n-1)pow(10,n-2)
             if ( mm  !=   0
            {
// 还不是个位
                
// 对低于当前位的位置先统计,当前位留到下一次
                 for ( int  j  =   0 ; j  <  curPosNum; j ++
                { 
                    
for ( int  k  =   0 ; k  <   10 ; k ++
                        countNum[k] 
+=  mm; 
                    countNum[j] 
+=  pow( 10.0 ,len - i - 1 ); 
                } 
                
if ! posNum.empty() ) 
                { 
                    
for ( int  m  =   0 ; m  <  posNum.size(); m ++
                    { 
                        
int  tt  =  posNum.at(m); 
                        countNum[tt] 
+=  ( pow( 10.0 ,len - i - 1 ) * curPosNum ); 
                    }        
                }    
                posNum.push_back(curPosNum);
                
if ( i  ==   0
                {
                    
// 去掉多余的0
                     for ( int  j  =   0 ; j  <  len - 1 ; j ++
                        countNum[
0 =  countNum[ 0 -  (len - j - 1 ) * pow( 10.0 ,j) * 9.0
                    
// 去掉全0,包括一个0的情况
                    countNum[ 0 -=  len - 1
                }                        
            } 
            
else
            {
// 位置来到个位上了
                 for ( int  m  =   0 ; m  <  posNum.size(); m ++
                { 
                    
int  tm  =  posNum.at(m); 
                    countNum[tm] 
+=   1
                } 
                
for ( int  n  =   1 ; n  <=  curPosNum; n ++
                { 
                    countNum[n] 
+=   1
                    
for ( int  mn  =   0 ; mn  <  posNum.size(); mn ++
                    { 
                        
int  tmn  =  posNum.at(mn); 
                        countNum[tmn] 
+=   1
                    } 
                } 
            } 
        } 
    } 
    
for ( int  i  =   0 ; i  <   10 ; i ++
    {
        cout
<< countNum[i] << endl; 
    }
    
return   0
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值