bzoj 1833 数字计数
题目大意:
给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次
思路:
不知道黄学长他们的dp都是怎么dp的
搞神的方法太强啦
%%%
数位乱搞。。
推了公式,然后每一位直接套用公式
每一位分3种情况
小于该位数字的直接+10的位数次方
等于的+10的位数减一次方再加上后面几位构成数字那么多
大于的+10的位数减一次方
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 using namespace std; 12 inline ll read() 13 { 14 ll x=0,f=1;char ch=getchar(); 15 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 16 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 17 return x*f; 18 } 19 ll res[10][2],a,b; 20 void solve(ll x,ll d) 21 { 22 ll k,t=1,p=0; 23 while(10*t<=x) t*=10,p++; 24 //cout<<x<<" "<<t<<" "<<p; 25 while(t) 26 { 27 k=(x/t)%10; 28 res[0][d]+=x/(t*10)*pow(10,p); 29 if(!k) res[0][d]-=pow(10,p)-x%t-1; 30 else res[k][d]+=x/(t*10)*pow(10,p)+x%t+1; 31 for(int i=1;i<k;i++) 32 res[i][d]+=(x/(t*10)+1)*pow(10,p); 33 for(int i=k+1;i<=9;i++) 34 res[i][d]+=x/(t*10)*pow(10,p); 35 t/=10,p--; 36 } 37 } 38 int main() 39 { 40 a=read(),b=read(); 41 solve(a-1,0);solve(b,1); 42 for(ll i=0;i<9;i++) printf("%lld ",res[i][1]-res[i][0]); 43 printf("%lld",res[9][1]-res[9][0]); 44 }