//
// 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.