统计数字

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

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

输入: 每个输入只有行,给出表示书的总页码的整数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;
}

 


 

posted @ 2009-12-29 22:47  blessw  阅读(293)  评论(0编辑  收藏  举报