标签:ace copy 复制 text lse 数位dp data pre 结果
两个数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\n",bn[i] - an[i]); 33 } 34 return 0; 35 }
标签:ace copy 复制 text lse 数位dp data pre 结果
原文地址:https://www.cnblogs.com/zllwxm123/p/9941998.html