数位DP入门 BZOJ 1833 题解(需要复习)
来源:互联网 发布:mac免费软件 编辑:程序博客网 时间:2024/06/09 19:50
显然,这篇博客受PoPoQQQ的影响,代码自己敲了一遍,基本上和PoPoQQQ的代码一样,在这里写一下题解
题目:
http://www.lydsy.com/JudgeOnline/problem.php?id=1833
1833: [ZJOI2010]count
数字计数
Time Limit: 3 Sec Memory Limit: 64 MB
Submit: 3421 Solved: 1510
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。
注释代码:
#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#define dnt long longusing namespace std;dnt cnt[10],f[100];void Resolve(dnt x,dnt pos){ //在现在这个函数里,我们可以发现这里有个while来处理当前位的信息,请大家模拟12345(认真模拟一下就懂了),之前是处理的now/pos作为x传过来的,这样一来可以处理该位是x%10带来的贡献 x=10 pos=1000 while(x){ cnt[x%10]+=pos; x/=10; }} void Digital_DP(dnt x,int ff){ int i,j; dnt pos,now; //先定义一个pos表示当前数位的意义 for(i=1,pos=10;pos<x;i++,pos*=10){ for(j=0;j<=9;j++){ cnt[j]+=f[i-1]*9*ff; //可以这样考虑,i-1的整体区间的左边添加了一个数,但是不能为0,所以*9(这是右边的区间对答案的贡献) } for(j=1;j<=9;j++){ cnt[j]+=pos/10*ff; //考虑的是最左边为j的情况,会对答案进行贡献该位的意义除10,例如j=1时,123456中的1对答案的贡献是100000,也就是pos/10(此时我们只考虑最高位,零头一会儿再处理) } } now=pos/=10;i--;//此时的now等于最高位的意义 //注意到pos大于了x才停止循环,所以往回走一步 while(now<x){ while(now+pos<=x){ dnt temp=now/pos; //temp为(当前累加起来的值/当前数位的意义),至于为什么要这么搞,下一个函数就清楚了 Resolve(temp,pos*ff); for(j=0;j<=9;j++){ cnt[j]+=f[i]*ff; } now+=pos;//该位的意义一步一步地累加到now里去 } pos/=10;i--; }} int main(){ dnt a,b,pos; int i; f[1]=1; for(i=2,pos=10;i<=12;i++,pos*=10){ f[i]=f[i-1]*10+pos; } //首先预处理出每一位数字包括前导0的i位数里有多少它,注意一点,所有的数在某一位包括前导0的情况下个数都是相等的,举个例子,对于小于十位数来说,所有数出现的机会是均等的,小于两位数,每个数出现的机会也是均等的,注意这里处理的是有前导0的,也就是说01,03,09这些都是合法的 cin>>a>>b; Digital_DP(b+1,1);//注意到这里是b+1,参看该函数里用的是统计小于该数的信息,也就刚好是1到b的信息 Digital_DP(a,-1);//函数传的参数1,-1到ff里,是为了实现一个函数实现区间1到b减去区间1到a-1的操作 for(i=0;i<=9;i++) printf("%lld%c",cnt[i],i==9?'\n':' '); //注意到这里的输出,我PE了一次 return 0;}
阅读全文
0 0
- 数位DP入门 BZOJ 1833 题解(需要复习)
- 数位DP入门后部分题解
- bzoj 1026(数位dp)
- 【BZOJ】【P1833】【ZJOI2010】【count 数字计数】【题解】【数位DP】
- [BZOJ 1833] count 数字计数 数位DP(附数位DP总结)
- BZOJ 1833 [ZJOI 2010] 数字统计 (数位DP)
- bzoj 1833: [ZJOI2010]count 数字计数(数位dp)
- BZOJ 1833 count 数字计数 (数位DP)
- HDU2089(数位dp入门)
- bzoj 1833 数字计数|数位dp
- bzoj 1833 count 数字计数 数位dp
- BZOJ 1833 数位DP 解题报告
- BZOJ 1833 count 数字计数 数位DP
- BZOJ 1026 windy数 (数位DP)
- BZOJ-1026-windy数(数位DP)
- bzoj 4521: [Cqoi2016]手机号码 (数位dp)
- 【bzoj 4521】 [Cqoi2016]手机号码(数位dp)
- bzoj 3780: 数字统计 (数位dp)
- react生命周期概括
- sudo和su命令简介
- centos上的多路车牌、人脸识别
- 基于DotNetBar的UI布局
- AsyncHttpClient的数据请求使用的封装
- 数位DP入门 BZOJ 1833 题解(需要复习)
- RSA算法原理(一)
- 如何在UE4 C++中进行按键绑定
- USACO section 1.3 Combination Lock
- mysql与jsp时间不对应
- shell脚本的简单学习
- 线段树相关
- Android Studio Error:null value in entry: outputDirectory=null编译报错问题
- MyBatis 拦截器(4)