题目
统计位数
- 题目描述:求数字n以内的正整数有多少位数字,不统计前导零。例如n=13时,13以内的正整数有12345678910111213,一共17位,则输出17
输入:
- 第一行一个数 T (T<=100),表述数据组数。
- 对于每组数据,第一行1个整数n,(1<=n<=10^9)
输出:
- 对于每组输出,输出一行,表示数字位数和。
样例输入:
2
13
4
- 样例输出:
17
4
解题思路
- 没有思路时,归纳:(
f(n)
f
(
n
)
表示n的统计位数)
- 如果 n≤9 n ≤ 9 ,则很简单,位数和就是n: f(n)=n f ( n ) = n
- 如果 n∈[10,99] n ∈ [ 10 , 99 ] ,位数和为 (n−9)×2+9 ( n − 9 ) × 2 + 9 : f(n)=(n−9)×2+f(9) f ( n ) = ( n − 9 ) × 2 + f ( 9 )
- 如果 n∈[100,999] n ∈ [ 100 , 999 ] ,位数和为 (n−99)×3+(99−10)×2+9 ( n − 99 ) × 3 + ( 99 − 10 ) × 2 + 9 : f(n)=(n−99)×3+f(99) f ( n ) = ( n − 99 ) × 3 + f ( 99 )
- …
规律基本出来了,
f(n)=(n−10K−1+1)∗K+f(10K−1−1) f ( n ) = ( n − 10 K − 1 + 1 ) ∗ K + f ( 10 K − 1 − 1 ) , if 10K−1<n≤10K,that is K=floor(log10n) if 10 K − 1 < n ≤ 10 K , that is K = floor ( log 10 n )需要注意的点
- 题中给出了n的限制: 1≤n≤109 1 ≤ n ≤ 10 9
代码
- 非递归
#include <iostream>
using namespace std;
int main()
{
int a, b, T;
long int tab[10]={0, 9, 9+90*2, 9+90*2+900*3, 9+90*2+900*3+9000*4, 9+90*2+900*3+9000*4+90000*5,
9+90*2+900*3+9000*4+90000*5+900000*6, 9+90*2+900*3+9000*4+90000*5+900000*6+9000000*7,
9+90*2+900*3+9000*4+90000*5+900000*6+9000000*7+90000000*8,
9+90*2+900*3+9000*4+90000l*5+900000*6+9000000*7+90000000*8+900000000*9l
};//9l, the 'l' is important
long int tab1[10]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
cin>>T;
for(int i=0;i<T;i++)
{
cin>>a;
int K=9;
while(a<tab1[K])
{
cout<<tab[K]<<endl; //for debug
K--;
}
cout<<tab[K]+(a-tab1[K]+1)*(K+1)<<endl;
}
return 0;
}
- 递归
#include <iostream>
#include <cmath>
using namespace std;
unsigned long int my_pow_10(unsigned int k)
{
unsigned long int tab[10]={1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
if(k<=9)
{
return tab[k];
}
else //error
{
return 0;
}
}
unsigned long int digital_num(unsigned int n, unsigned int K)
{
if(1 == K)
{
return n;
}
else
{
return (n-my_pow_10(K-1)+1)*K+digital_num(my_pow_10(K-1)-1, K-1);
}
}
int main()
{
int n, T;
cin>>T;
for(int i=0;i<T;i++)
{
cin>>n;
unsigned int K = (unsigned int)(log(n));
cout<<digital_num(n, K)<<endl;
}
return 0;
}