zoukankan      html  css  js  c++  java
  • 32 从1到n整数中1出现的次数

    输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。

    主要思路:设定整数点(如1、10、100等等)作为位置点i(对应n的各位、十位、百位等等),分别对每个数位上有多少包含1的点进行分析
        //根据设定的整数位置,对n进行分割,分为两部分,高位n/i,低位n%i
        //当i表示百位,且百位对应的数>=2,如n=31456,i=100,则a=314,b=56,此时百位为1的次数有a/10+1=32(最高两位0~31),每一次都包含100个连续的点,即共有(a%10+1)*100个点的百位为1
        //当i表示百位,且百位对应的数为1,如n=31156,i=100,则a=311,b=56,此时百位对应的就是1,则共有a%10(最高两位0-30)次是包含100个连续点,当最高两位为31(即a=311),本次只对应局部点00~56,共b+1次,所有点加起来共有(a%10*100)+(b+1),这些点百位对应为1
        //当i表示百位,且百位对应的数为0,如n=31056,i=100,则a=310,b=56,此时百位为1的次数有a/10=31(最高两位0~30)
        //综合以上三种情况,当百位对应0或>=2时,有(a+8)/10次包含所有100个点,还有当百位为1(a%10==1),需要增加局部点b+1
        //之所以补8,是因为当百位为0,则a/10==(a+8)/10,当百位>=2,补8会产生进位位,效果等同于(a/10+1)
     

    C++:

     1 class Solution {
     2 public:
     3     int NumberOf1Between1AndN_Solution(int n)
     4     {
     5         int cnt = 0 ;
     6         for(int m = 1 ; m <= n ; m*=10){
     7             int a = n/m ;
     8             int b = n%m ;
     9             cnt += (a+8)/10 * m + ((a%10 == 1) ? b+1 : 0) ;
    10         }
    11         return cnt ;
    12     }
    13 };
  • 相关阅读:
    【NOIP 2003】 加分二叉树
    【POJ 1655】 Balancing Act
    【HDU 3613】Best Reward
    【POJ 3461】 Oulipo
    【POJ 2752】 Seek the Name, Seek the Fame
    【POJ 1961】 Period
    【POJ 2406】 Power Strings
    BZOJ3028 食物(生成函数)
    BZOJ5372 PKUSC2018神仙的游戏(NTT)
    BZOJ4836 二元运算(分治FFT)
  • 原文地址:https://www.cnblogs.com/mengchunchen/p/9004203.html
Copyright © 2011-2022 走看看