1049. Counting Ones (30)

来源:互联网 发布:单例模式 java 双重锁 编辑:程序博客网 时间:2024/05/16 18:04

1049. Counting Ones (30)

时间限制
100 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

The task is simple: given any positive integer N, you are supposed to count the total number of 1's in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1's in 1, 10, 11, and 12.

Input Specification:

Each input file contains one test case which gives the positive N (<=230).

Output Specification:

For each test case, print the number of 1's in one line.

Sample Input:
12
Sample Output:
5

提交代码

解题思路:

如果每个数遍历一遍计算里面的1的个数肯定是会超时的,仔细观察就可以发现其中的规律。我们可以从每一位开始计算1的个数。

以40123位例。从个位到万位进行计算。

个位:

个位数3,左边4012右边0。个位3可以取到1,左边0000到4012,有4013个数,4013乘以10的0次方。

十位:

十位数2,左边401,右边3。左边000到401.右边可以取到0到9。十位取1时可以表示为0001x到4011x。总共有402*10个数。

百位:

百位数1,左边40,右边23。

1、左边00到39,右边xx。40*10的2次方个。注意为什么不能取到40。如果取了40后面就不能取到99。

2、左边取40,百位1,,右边可以去00到23.共23+1=24个。

千位

千位0,左边4,右边123。01xxx到31xxx,4乘以10的三次方。

万位

万位4,左边0,右边0123,1xxxx,1*10的四次方个。

下面是具体的计算规则:

以ans表示1的个数,从低位到高位依次枚举每一位,其中给出a表示后面的位数。

设当前位的数位数字为now,左边的数位l,右边的数位r;

根据now的值分三种情况讨论:

1、now等于0   ans+=l*a

2、now等于1   ans+=l*a+r+1;

3、now大于1  ans+=(l+1)*a;

下面是具体代码:

#include<iostream>using namespace std;int main(){int n;int a = 1,ans = 0;int l,r,now;scanf("%d",&n); while(n/a != 0){l = n/(a*10);now = n/a%10;r = n%a;if(now == 0){ans += l*a;}else if(now == 1){ans += l*a+r+1;}else ans += (l+1)*a;a *= 10;}printf("%d\n",ans);return 0;} 



原创粉丝点击