• (算法)从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;
    }
  • 相关阅读:
    zzuli-2259 matrix
    【vlan之四种方式链路认证组网]
    【ppp-chap,pap,mp,mp-group】
    【ospf-基础配置】
    【rip-基础配置】
    【静态路由】
    【nat---basic,napt,easy ip】
    【acl-访问控制列表】
    【交换接口的-绑定-认证-隔离】
    【vlan-给予mac地址认证】
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4908899.html
Copyright © 2020-2023  润新知