码迷,mamicode.com
首页 > 其他好文 > 详细

[ZJOI2010]数字计数

时间:2018-03-01 13:29:21      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:bsp   文件中   col   reg   个数   数位   names   输出   algo   

题目描述

给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。

输入输出格式

输入格式:

输入文件中仅包含一行两个整数a、b,含义如上所述。

输出格式:

输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。

输入输出样例

输入样例#1: 复制
1 99
输出样例#1: 复制
9 20 20 20 20 20 20 20 20 20

说明

30%的数据中,a<=b<=10^6;

100%的数据中,a<=b<=10^12。

数位dp的套路记忆化搜索

枚举d=0~9,分别统计

f[pos][sum]表示当前在pos位,d这个数出现个数

flag表示是否限位,k表示是否前导0

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 typedef long long lol;
 8 int s[13],len;
 9 lol A,B,f[21][21];
10 lol dfs(int pos,int sum,int flag,int k,int d)
11 {int i;
12   lol cnt=0;
13   if (pos<=0) return sum;
14   if (!flag&&k&&f[pos][sum]!=-1) return f[pos][sum];
15   int ed=9;
16   if (flag) ed=s[pos];
17   for (i=0;i<=ed;i++)
18     {
19       if (k==0&&i==0)
20     cnt+=dfs(pos-1,sum,flag&&(i==ed),0,d);
21       else
22     {
23       cnt+=dfs(pos-1,sum+(i==d),flag&&(i==ed),1,d);
24     }
25     }
26   if (!flag&&k) f[pos][sum]=cnt;
27   return cnt;
28 }
29 lol solve(lol x,int d)
30 {int i,j,k;
31   memset(f,-1,sizeof(f));
32   len=0;
33   while (x)
34     {
35       s[++len]=x%10;
36       x/=10;
37     }
38   return dfs(len,0,1,0,d);
39 }
40 int main()
41 {int i;
42   cin>>A>>B;
43   printf("%lld",solve(B,0)-solve(A-1,0));
44   for (i=1;i<=9;i++)
45     {
46       printf(" %lld",solve(B,i)-solve(A-1,i));
47     }
48 }

 

[ZJOI2010]数字计数

标签:bsp   文件中   col   reg   个数   数位   names   输出   algo   

原文地址:https://www.cnblogs.com/Y-E-T-I/p/8487775.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!