PAT甲级1049 Counting Ones【规律】

题目https://pintia.cn/problem-sets/994805342720868352/problems/994805430595731456

题意:

给定n,问0~n中,1的总个数是多少。

思路:

问的是总个数,所以不需要考虑重复,只用考虑每一位上的贡献就行了。

将数字分成三部分,left(共i位),now和right(共j位)

如果当前now是0, 那么所有前i位是[0,left)的数字都+1个贡献,这些数一共有$left*10^j$个

如果当前now是[2,9],那么所有前i位是[0,left]的数字都+1个贡献,这些数一共有$(left+1)*10^j$个

如果当前now是1,那么这一位是1的数可以是,前i位为[0,left)的所有数,或是前i位刚好是left而后j位是[0,right]的。

一共有$left*10^j+right+1$个

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<map>
 4 #include<set>
 5 #include<iostream>
 6 #include<cstring>
 7 #include<algorithm>
 8 #include<vector>
 9 #include<cmath> 
10 #include<stack>
11 #include<queue>
12 
13 #define inf 0x7fffffff
14 using namespace std;
15 typedef long long LL;
16 typedef pair<string, string> pr;
17 
18 LL n;
19 LL r;
20 
21 int main()
22 {
23     LL p = 1;
24     cin>>n;
25     LL ans = 0;
26     LL tmp = n;
27     while(n){
28         if(n % 10 == 0){
29             //cout<<n / 10 * p<<endl;
30             ans += n / 10 * p;
31         }
32         else if(n % 10 == 1){
33             //cout<<(n / 10 * p) + r + 1<<endl;
34             ans += (n / 10 * p) + r + 1;
35         }
36         else{
37             //cout<<(n / 10 + 1) * p<<endl;
38             ans += (n / 10 + 1) * p;
39         }
40         
41     
42         n /= 10;
43         p *= 10;
44         r = tmp % p;
45     }
46     
47     cout<<ans<<endl;
48     return 0;
49 }

猜你喜欢

转载自www.cnblogs.com/wyboooo/p/10662871.html