累积1的数目

http://zju.acmclub.com/index.php?app=problem_title&id=1&problem_id=2154

问题如下:给定1个十进制正整数N,计算从1到N的所有整数中“数字1”出现的个数

例如:N=12,序列={1,2,3,4,5,6,7,8,9,10,11,12},其中出现“1”的个数是5;故f(12)=5

解法:对于此题,《编程之美》中给出了一个巧妙的解法。

主要思路是:将总结果拆分成几个结果的和,如对于一个5位的整数abcde,序列中百位上出现1的次数受百位上的数字c影响,千位上出现1的次数受b影响,依此类推;最后将各个数位上1出现的次数加起来即为总和。

归纳总结,分成以下三种情况:以百位上的数字c为例:

1.如果c=0;则1在百位出现的次数受高位上的数字影响,为高位数字ab*100(100为当前乘数因子,在个位时为1,十位为10,百位为100等等)

2.如果c=1;则1在百位出现的次数既受高位影响,也受低位影响,高位影响的个数为高位数字ab*100(当前因子),低位影响的个数为低位数字de+1

3.如果c>1;则1在百位出现的次数仅受高位上的数字影响,为(ab+1)*100(当前因子)


cpp代码:

#include <iostream>
using namespace std;
int CountOne(int num){
    int mod,cnt=0,factor=1;
    int tmp=num;
    while(num!=0){
        mod=num%10;
        switch(mod){
        case 0:
            cnt+=(tmp/(factor*10))*factor;
            break;
        case 1:
            cnt+=(tmp/(factor*10))*factor+(tmp%factor)+1;
            break;
        default:
            cnt+=(tmp/(factor*10)+1)*factor;
            break;
        }
        num/=10;
        factor*=10;
    }
    return cnt;
}

int main(){
    int n;
    while(cin>>n){
        cout<<CountOne(n)<<endl;
    }
    return 0;

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值