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 }
View Code

 

 

1833: [ZJOI2010]count 数字计数

Time Limit: 3 Sec  Memory Limit: 64 MB
Submit: 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

 

posted @ 2016-06-19 21:35  晴歌。  阅读(224)  评论(0编辑  收藏  举报