zoukankan      html  css  js  c++  java
  • 1049. Counting Ones (30)

    题目例如以下:

    The task is simple: given any positive integer N, you are supposed to count the total number of 1's in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1's in 1, 10, 11, and 12.

    Input Specification:

    Each input file contains one test case which gives the positive N (<=230).

    Output Specification:

    For each test case, print the number of 1's in one line.

    Sample Input:
    12
    
    Sample Output:
    5
    


    对于此类问题。应当从找一般化的规律为主。而不应当试图推导排序组合的数学表达式。

    这道题目的难点在于每一位都有出现1的可能,比如100,010,001。110等,假设依照排序组合考虑,由于要计数1的个数,因此对于1的个数不同。要分别对待,这将会是非常棘手的问题。

    假设换个思路,从每一位入手,研究每一位的规律,则会使得问题简单得多,这样的研究方法是科学的。由于每一位都考虑了自己的1,那么合起来对于多个1的问题就自然考虑进来了。比如N=12时。我们分别考虑以下的情况:

    个位出现1的有1。11,十位出现1的有10。11。12,我们看到,对于11这样的多个1的情况,正好计算了两次,对于多位也是这个道理。

    以下我们从一个5位数入手,研究百位不同一时候,百位为1的全部情况的计算:

    我们以12045、12145、12245为例。
    12045:
    百位为0。那么高位不变低位部分无法产生类似1XX的数字,因此考虑高位,注意到仅仅要比当前值小就能够,因此可选择:00100-00199。01100-01199 ... 11100-11199 一共12*100=1200,观察到等于比当前高位的数字*100。


    也就是:高位数字*100,注意到这个100和当前考虑的位有关,百位为100,从低位为第1位開始计算第x位为10的x次方,也就是说对不同的位这个100应该换成对应的值

    12145:
    百位为1,那么高位不变,低位从100-145都能够。共45+1=46个,高位仍然能够产生百位为0时的变化。共1200+46+1246种
    也就是:高位数字*100 + 低位数字+1
    12245:
    对于百位大于1的情况,我们仅仅须要考虑高位就可以列全全部,从00100-00199到12100-12199。共13*100=1300
    也就是:(高位数字 + 1)*100


    攻克了这个问题。以下要解决的是取出高位数、当前位、低位数的问题,我们以6位数abcdef取出百位为例:

    对于abcdef,设因数factor=100。即要取出百位d
    依照常规方法,百位 = abcdef / factor % 10 = abcd % 10 = d
    高位数字 = abcdef / factor / 10 = abc
    低位数字 = abcdef - abcd00 = ef
    而abcd00 = (abcdef / factor) * factor = abcd00
    所以低位数字 = abcdef - ( abcdef / factor ) * factor

    这时候,factor就是前面我们要找的从低位開始算的10的x次方。因此编写代码变得简单,仅仅须要从低位開始。也就是factor从1開始。每次乘以10,直到超出当前值,此时N/factor=0。停止运算。


    代码例如以下:

    #include <iostream>
    #include <stdio.h>
    
    using namespace std;
    
    int compute(int N){
        int factor = 1;
        int low = 0;
        int high = 0;
        int now = 0;
        int cnt = 0;
    
        while(N / factor != 0){
            now = (N / factor) % 10;
            high = N / factor / 10;
            low = N - (N / factor) * factor;
    
            switch(now){
            case 0:
                cnt += high * factor;
                break;
            case 1:
                cnt += high * factor + low + 1;
                break;
            default:
                cnt += (high + 1) * factor;
            }
    
            factor *= 10;
    
        }
    
        return cnt;
    
    }
    
    int main()
    {
        int N;
        while(scanf("%d",&N) != EOF){
            cout << compute(N) << endl;
        }
    
        return 0;
    }


  • 相关阅读:
    第一章 第二节逻辑代数基础
    第一章 第一节数制与编码
    Altium Designer多原理图、PCB更新处理
    AD添加LOGO的方法
    XML中<beans>属性
    程序员值得学习的技术博客
    设计模式
    js分页实例
    Java构造和解析Json数据的方法
    H5+ 移动app学习之三 App离线存储
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5385923.html
Copyright © 2011-2022 走看看