BZOJ_1833_[ZJOI2010]_数字计数_(数位dp)
描述
http://www.lydsy.com/JudgeOnline/problem.php?id=1833
统计\(a~b\)中数字\(0,1,2,...,9\)分别出现了多少次.
分析
数位dp真是细节又多又容易出错,我都懒得看题解,所以也就懒得写题解了...
注意细节吧还是...
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 ll a,b; 6 ll A[10],B[10],num[15]; 7 ll f[14][10][10]; 8 9 void solve(ll x,ll *a){ 10 if(x==0) return; 11 if(x<10){ 12 for(int i=1;i<=x;i++) a[i]=1; 13 return; 14 } 15 int cnt=0; 16 ll t=0; 17 while(x) num[++cnt]=x%10, x/=10; 18 for(int i=1;i<cnt;i++)for(int j=1;j<=9;j++)for(int k=0;k<=9;k++) a[k]+=f[i][j][k]; 19 for(int i=1;i<cnt;i++){ 20 for(int j=0;j<num[i];j++)for(int k=0;k<=9;k++) a[k]+=f[i][j][k]; 21 a[num[i]]+=t+1; t=t+num[i]*(ll)pow(10,i-1); 22 } 23 for(int j=1;j<num[cnt];j++)for(int k=0;k<=9;k++) a[k]+=f[cnt][j][k]; 24 a[num[cnt]]+=t+1; 25 } 26 int main(){ 27 scanf("%lld%lld",&a,&b); 28 for(int i=0;i<=9;i++) f[1][i][i]=1; 29 for(int i=2;i<=13;i++){ 30 for(int j=0;j<=9;j++)for(int k=0;k<=9;k++) f[i][0][k]+=f[i-1][j][k]; 31 for(int j=1;j<=9;j++)for(int k=0;k<=9;k++) f[i][j][k]=f[i][0][k]; 32 for(int j=0;j<=9;j++) f[i][j][j]+=(ll)pow(10,i-1); 33 } 34 solve(b,B); solve(a-1,A); 35 for(int k=0;k<9;k++) printf("%lld ",B[k]-A[k]); 36 printf("%lld\n",B[9]-A[9]); 37 return 0; 38 }
1833: [ZJOI2010]count 数字计数
Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 2569 Solved: 1132
[Submit][Status][Discuss]
Description
给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。
Input
输入文件中仅包含一行两个整数a、b,含义如上所述。
Output
输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。
Sample Input
1 99
Sample Output
9 20 20 20 20 20 20 20 20 20
HINT
30%的数据中,a<=b<=10^6;
100%的数据中,a<=b<=10^12。
Source