[美团笔试算法题] 统计位数

题目

统计位数

  • 题目描述:求数字n以内的正整数有多少位数字,不统计前导零。例如n=13时,13以内的正整数有12345678910111213,一共17位,则输出17
  • 输入:

    • 第一行一个数 T (T<=100),表述数据组数。
    • 对于每组数据,第一行1个整数n,(1<=n<=10^9)
  • 输出:

    • 对于每组输出,输出一行,表示数字位数和。
  • 样例输入:

2
13
4
  • 样例输出:
17
4

解题思路

  1. 没有思路时,归纳:( f ( n ) 表示n的统计位数)
    • 如果 n 9 ,则很简单,位数和就是n: f ( n ) = n
    • 如果 n [ 10 , 99 ] ,位数和为 ( n 9 ) × 2 + 9 : f ( n ) = ( n 9 ) × 2 + f ( 9 )
    • 如果 n [ 100 , 999 ] ,位数和为 ( n 99 ) × 3 + ( 99 10 ) × 2 + 9 : f ( n ) = ( n 99 ) × 3 + f ( 99 )
  2. 规律基本出来了,
    f ( n ) = ( n 10 K 1 + 1 ) K + f ( 10 K 1 1 ) , if   10 K 1 < n 10 K , that is  K = floor ( log 10 n )

  3. 需要注意的点

    • 题中给出了n的限制: 1 n 10 9

代码

  1. 非递归
#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;
}
  1. 递归
#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;
}

猜你喜欢

转载自blog.csdn.net/smallflyingpig/article/details/80028649
今日推荐