PAT_1049. Counting Ones

来源:互联网 发布:淘宝一个月能赚多少钱 编辑:程序博客网 时间:2024/05/29 09:01
////  main.cpp//  PAT_1049. Counting Ones////  Created by wjq on 17/5/14.//  Copyright © 2017年 wjq. All rights reserved.//#include <iostream>using namespace std;int count1(int num){    int factor=1,sum=0;    while(num/factor!=0)    {        int higher=num/(factor*10);        int lower=num%factor;        int cur=(num/factor)%10;        switch(cur)        {            case 0:                sum+=higher*factor;                break;            case 1:                sum+=higher*factor+lower+1;                break;            default:                sum+=(higher+1)*factor;                break;        }        factor*=10;    }    return sum;}int main(int argc, const char * argv[]){    int N;    cin>>N;    cout<<count1(N)<<endl;}


这是一道数字规律题.

题意是求解从1-N的所有数字出现的1的之和.

如果直接暴力求解,一个for循环,很明显会导致超时.


思路:

给定一个N,我们考虑从N的每一位来考虑问题.

比如说我随便给出一个数字 12345

1.

从1-12345中,个位是1的数字有哪些?

1 21 31 41 51 ....91 101 111 121 131 141 151 .....12341

我们把这一串数字最右边的1去掉.你发现,得到了一个串0 1 2 3 4 5 6 ....1234

所以从1-12345中,个位是1的数字有1235个.

2.

从1-12345,十位是1的数字有哪些?

10-19

110-119

120-129

...

12310-12319

你把十位和个位去掉,就得到0 1 2 3 4 5 ....123 这样串.

所以就相当于有124个(10-19)的循环,因此十位是1的数字有124*10=1240个.

3.

从1-12345,百位是1的数字有哪些?

100-199

1100-1199

2100-2199

...

12100-12199

你把百位.十位.和个位去掉,就得到0 1 2 3 ... 12 这样一个串

所以就相当于有13个(100-199)的循环,因此百位是1的数字有13*100=1200个.

千位和万位的分析其实是一样的.


从上面的分析我们可以得到规律. 

某个位出现的次数是由高位来决定的.

某个位出现的数字个数=(高位+1)*位数


我们只分析了一个数字的规律,肯定是不完全的,再给出一个数字11111

1.个位

1 11 21 31 41 51 ....11111

一共1111个数

2.十位

10-19

110-119

...

10810-10819

10910-10919

11010-11019

去掉十位和个位,得到 0,1,2,3,4...109 110总共111个循环

特殊的[11110-11111]

你会看到,在十位本身是1的情况下,个位数会影响范围.导致11110-11119是不对的,但如果十位数是(2,3,4,5,6,7,8,9).我们是可以得到11110-11119这样一个范围的.

在这个例子中(由于十位本身=1).

十位是1的数字个数=高位(111)*位数(10)+低位(1)+1

3.百位

100-199

1100-1199

2100-2199

....

9100-9199;

10100-10199;

特殊的[11100-11111]


0,1,2,3,4...10个(100-199)的循环.

再加上一个特殊的串[11100-11111]

百位是1的数字个数=(高位)11*(位数)100+低位(11)+1


至此,我们已经将某一位上出现1,2,3,4,5,6,7,8,9的情况讨论过了.那么如果某一位上出现0呢?

看下一个数字 10011

百位上的数字是0.考虑百位上出现1的数字有哪些.

有了之前的经验,我们先得出该位的高位是10,低位是11

100-199

1100-1199

2100-2199

....

9100-9199

很容易的到.

如果该数字某一位上是0.

那么该位上出现1的数字次数=高位*位数.


总结一下.

我们的思路就是对每一位进行处理.

每一位进行处理的时候要考虑分类.

1.当前位是0的情况

数字次数=高位*位数

2.当前位是1的情况

数字次数=高位*位数+低位+1

3.当前位是2-9的情况

数字次数=(高位+1)*位数


在公式中.举个例子,如数字2345

考虑个位,高位=234,当前位=5,低位=0,位数=1

考虑十位,高位=23,当前位=4,低位=5,位数=10

考虑百位,高位=2,当前位=3,低位=45,位数=100

考虑千位,高位=0,当前位=2,低位=345,位数=1000.





0 0