题目
统计位数
- 题目描述:求数字n以内的正整数有多少位数字,不统计前导零。例如n=13时,13以内的正整数有12345678910111213,一共17位,则输出17
输入:
- 第一行一个数 T (T<=100),表述数据组数。
- 对于每组数据,第一行1个整数n,(1<=n<=10^9)
输出:
- 对于每组输出,输出一行,表示数字位数和。
样例输入:
2
13
4
- 样例输出:
17
4
解题思路
- 没有思路时,归纳:(
表示n的统计位数)
- 如果 ,则很简单,位数和就是n:
- 如果 ,位数和为 :
- 如果 ,位数和为 :
- …
规律基本出来了,
,需要注意的点
- 题中给出了n的限制:
代码
- 非递归
#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;
}