1042 数字0-9的数量
给出一段区间a-b,统计这个区间内0-9出现的次数。
比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次。
输入
两个数a,b(1 <= a <= b <= 10^18)
输出
输出共10行,分别是0-9出现的次数
输入样例
10 19
输出样例
1 11 1 1 1 1 1 1 1 1
题意很明确,
其实只要能求的到b的就可以.
然后用val(b) - val(a-1)就能得出结果
我的思路是既然要求1到n的,那么每次我只计算1到n的每个数的最后一位.
并且记录最后一位的状态变化.
比如求2018
那么第一次就是2018/10 = 201 2018%10 = 8
那么从0到9每个位上就能加201, 然后 1到8都加1
下一次就是201/10 = 20 201%10 = 1
那么0到9每位加20*10 ,然后从1加9;
仔细看代码就知道我的思路是什么了.
每次都减掉最后一位数.
1 #include <bits/stdc++.h> 2 #define ll long long int 3 using namespace std; 4 ll a,b; 5 ll an[10], bn[10]; 6 void solve(ll x,ll xn[]){ 7 ll ans = 1; 8 ll cnt = 0; 9 while(x){ 10 ll aa = x/10; 11 for(int i = 0; i <= 9; i++){ 12 if(i == 0 && x%10 == 0) 13 xn[i] += (aa - 1)*ans; 14 else 15 xn[i] += aa*ans; 16 } 17 ll bb = x%10; 18 for(int i = 1; i < bb; i++){ 19 xn[i] += ans; 20 } 21 xn[bb] += cnt + 1; 22 cnt = cnt + (x%10 )*ans; 23 ans *= 10; 24 x /= 10; 25 } 26 } 27 int main(){ 28 scanf("%lld%lld", &a,&b); 29 solve(b, bn); 30 solve(a - 1, an); 31 for(int i = 0; i <= 9; ++i){ 32 printf("%lld ",bn[i] - an[i]); 33 } 34 return 0; 35 }
数位dp
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #define LL long long 7 using namespace std; 8 //循环两遍,sumright-sumleft 9 //10132 10 //==0:pre*after !=0:cur*pre*对应位数+after 11 //0 + 132 + 10*cur*100+after + 101*cur*100*10+2 +1013*1 12 //19 1* 13 LL ans[10]; 14 void solve(LL n,bool f) 15 { 16 LL cur,pre,after,temp=1,sign=f?1:-1; 17 int cnt = 0; 18 while((n/temp)!=0) 19 { 20 cur = (n/temp)%10; 21 pre = (n/(temp*10)); 22 after = n - (n/temp)*temp; 23 //cout<<pre<<' '<<cur<<' '<<after<<endl; 24 int tmp = after,mul=1; 25 while(tmp){mul*=10;tmp/=10;} 26 //cout<<" m is "<<mul<<endl; 27 for(int i=0;i<10;i++) 28 { 29 if(cur>i) ans[i]+=(pre+1)*temp*sign; 30 if(cur<i) ans[i]+=pre*temp*sign; 31 if(cur==i) ans[i]+=(pre*temp+after+1)*sign; 32 } 33 ans[0]-=temp*sign; 34 temp*=10; 35 } 36 } 37 //10+1+1 38 int main() 39 { 40 LL l,r; 41 bool f; 42 cin>>l>>r; 43 f = false; 44 solve(l-1,f); 45 f = true; 46 solve(r,f); 47 for(int i=0;i<10;i++) 48 { 49 cout<<ans[i]<<endl; 50 } 51 return 0; 52 }