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 }