• (算法)从0到n整数中数字2出现的次数


    题目:

    数出0到n(含)中数字2出现了几次。

    思路:

    1、暴力方法,数出每个数字包含几个2,然后累加起来。

    2、分析:分别考虑数字n每一位出现2的次数,如123123;

    从左往右考虑4123123;

    考虑第一个1(即第6位),该位出现2的次数为4*10^6/10;

    考虑第一个2(即第5位),该位出现2的次数为41*10^5/10+3123+1;

    考虑第一个3(即第4位),该位出现2的次数为(412+1)*10^4/10;

    附:除以10的原因在于:每10个数字,任意位出现2的概率为1/10.

    总结规律:

    第i位出现2个次数与该位所在的数字有关:

    当第i位的数字小于2,出现次数就等于比其高位部分的数字*10^i/10,

    当第i位的数字等于2,出现次数就等于比其高位部分的数字*10^i/10+n%(10^i),

    当第i位的数字大于2,出现次数就等于(比其高位部分的数字+1)*10^i/10。

    代码:

    #include<iostream>
    #include<sstream>
    #include<math.h>
    using namespace std;
    
    template<class out_T,class in_T>
    out_T convert(const in_T &t){
        stringstream ss;
        out_T result;
        ss<<t;
        ss>>result;
        return result;
    }
    
    int count2sInRangeAtDigit(int number,int d){
        int powerOf10=pow(10,d);
        int nextPowerOf10=powerOf10*10;
        int right=number%powerOf10;
    
        int roundDown=number-number%nextPowerOf10;
        int roundUp=roundDown+nextPowerOf10;
    
        int digit=(number/powerOf10)%10;
        if(digit<2)
            return roundDown/10;
        else if(digit==2)
            return roundDown/10+right+1;
        else
            return roundUp/10;
    }
    
    int count2sInRange(int number){
        int count=0;
        string str;
        str=convert<string>(number);
        int len=str.size();
    
        for(int digit=0;digit<len;digit++)
            count+=count2sInRangeAtDigit(number,digit);
        return count;
    }
    
    int main(){
        int n;
        while(cin>>n){
            cout<<count2sInRange(n)<<endl;
        }
        return 0;
    }
  • 相关阅读:
    SVN服务的配置与管理
    SVN配置多仓库与权限控制
    SVN使用详解
    这个问题他又来了,如何学编程!
    乘风破浪的程序员们
    Java 学习路线(史上最全 2020 版 ~ 持续更新中)
    P4782 【模板】2-SAT 问题
    HDU
    2020.8.3
    Interesting Computer Game
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4908899.html
Copyright © 2020-2023  润新知