PAT.1049 Counting Ones(排列组合)

1049 Counting Ones (30分)

 

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 (≤).

Output Specification:

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

Sample Input:

12

Sample Output:

5

思路:排列组合,考虑每一位为1时,其他位置的可能性,按照排列组合公式即可计算出。

假设对于303这个数字,令now为当前处理的这一位数,left为n刨去now及其他左边位数的值,
similarly right为右,再假设cnt为1e(now所在的位数,假设从数字最右边第零位开始)。
so
当now > 1时,左边可取0 ~ left的任意数字,右边 0 ~ cnt - 1的任意数字,因此
此时ans += (1 + left) * cnt。
当now == 1时,左边取0~left - 1任意数字时右边任取0~cnt - 1的数字,左边为left时,右边
仅能取 0~right的数字,因此 ans += left * cnt + right + 1。
当now == 0时,左边取0~left - 1任意数字,右边任取0~cnt - 1的人数,因此ans += left * cnt;
  


 1 #include <cstdio>
 2 using namespace std;
 3 
 4 int main() {
 5     int n;
 6     scanf("%d", &n);
 7     int temp = n;
 8     int cnt = 1;
 9     long long ans = 0;
10     int yu = 0;
11     while(temp) {
12         if(temp % 10 > 1) {
13             ans += (temp / 10 + 1) * cnt;
14         }
15         else if(temp % 10 == 1) {
16             ans += (temp / 10) * cnt + (yu + 1);
17         }
18         else {
19             ans += (temp / 10) * cnt; 
20         }
21         yu = (temp % 10) * cnt + yu;
22         cnt *= 10;
23         temp /= 10;
24     }
25     printf("%lld\n", ans);
26     return 0;
27 }

 



posted @ 2020-05-29 21:46  Cruel_King  阅读(110)  评论(0编辑  收藏  举报