BZOJ-1833 [ZJOI2010]count 数字计数 数位DP
来源:互联网 发布:centos keepalived nfs 编辑:程序博客网 时间:2024/06/05 04:15
大家都很强, 可与之共勉。
1833: [ZJOI2010]count 数字计数
Time Limit: 3 Sec Memory Limit: 64 MB
Submit: 3440 Solved: 1518
[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
Day1
Day1
显然,我们可以先计算出[1,a-1],[1,b]中每个数字出现的个数,然后相减即可。问题变为:给一个数n,求1,2,…,n中每个数字出现的次数。
以下叙述中,“i位”都是从低位向高位数。
首先,我们允许前导0,也不考虑数大小的上限,在位数一定时,设为i,每种数字出现的次数是相同的,记为f(i)。不难得出递推式f(i)=10*f(i-1)+10^(i-1)(将第i位和前i-1位的数字分开考虑即可)。
继续,如果仍然允许前导0,但将数的上限考虑进来的话,我们只需要从高位向低位计算。设当前为第i位,n的这一位的数字为k,那么对于那些这一位数字小于k的数,他们的前i-1位是没有数的大小上限的,每个数字累加k*f(i-1)即可,同时0~k-1的数累加10^(i-1);而对于那些这一位的数字恰好为k的数,为了不超过上限,应累加前i-1位的数字形成的数+1。
最后,如何处理前导0呢?
其实,假设n有m位,我们只需要先统计出1,2,…m-1位数的情况(而这些是没有上限的,会比较方便),计算时而且保证这些数的首位不为0,然后对于m位同样的在最高位的时候不将0计算进来即可。
#include <cstdio>int num[20] ;long long a, b, f[20], pow[20] ;long long cnta[10], cntb[10] ;inline void Digit_Dp ( long long n, long long* cnt ) { if ( !n ) return ; long long N = n ; int M ; for ( M = 0 ; N ; num[++ M] = N % 10, N /= 10 ) ; for ( int i = 1 ; i < M ; ++ i ) { cnt[0] += f[i - 1] * 9 ; for ( int j = 1 ; j < 10 ; ++ j ) cnt[j] += f[i - 1] * 9 + pow[i - 1] ; } n -= num[M] * pow[M - 1] ; for ( int i = 1 ; i < num[M] ; ++ i ) cnt[i] += pow[M - 1] ; for ( int i = 0 ; i < 10; ++ i ) cnt[i] += f[M - 1] * ( num[M] - 1 ) ; cnt[num[M]] += n + 1 ; for ( int i = M - 1 ; i ; -- i ) { n -= num[i] * pow[i - 1] ; for ( int j = 0 ; j < num[i] ; ++ j ) cnt[j] += pow[i - 1] ; for ( int j = 0 ; j < 10; ++ j ) cnt[j] += f[i - 1] * num[i] ; cnt[num[i]] += n + 1 ; }}int main ( ) { pow[0] = 1 ; for ( int i = 1 ; i < 15 ; ++ i ) { f[i] = f[i - 1] * 10 + pow[i - 1] ; pow[i] = pow[i - 1] * 10 ; } scanf ( "%lld%lld", &a, &b ) ; Digit_Dp ( a - 1, cnta ) ; Digit_Dp ( b, cntb ) ; for ( int i = 0 ; i <= 9 ; ++ i ) printf ( "%lld%c", cntb[i] - cnta[i], ( i ^ 9 ) ? ' ' : '\n' ) ;}
- BZOJ 1833 ZJOI2010 count 数字计数 数位DP
- BZOJ 1833 [ZJOI2010]count 数字计数(数位dp)
- 【BZOJ 1833】 [ZJOI2010]count 数字计数|数位DP
- bzoj 1833: [ZJOI2010]count 数字计数(数位dp)
- [bzoj 1833] [ZJOI2010]count 数字计数:数位DP
- BZOJ-1833 [ZJOI2010]count 数字计数 数位DP
- bzoj 1833 [ZJOI2010]count 数字计数 数位dp
- 1833: [ZJOI2010]count 数字计数 数位dp
- 【BZOJ】【P1833】【ZJOI2010】【count 数字计数】【题解】【数位DP】
- bzoj1833: [ZJOI2010]count 数字计数 数位dp
- [BZOJ1833] [ZJOI2010]count 数字计数 && 数位DP
- 【bzoj1833】[ZJOI2010]count 数字计数 数位DP
- Bzoj1833:[ZJOI2010]count 数字计数:数位dp
- bzoj1833[ZJOI2010]count 数字计数 数位DP
- 【bzoj 1833】【codevs 1359】 [ZJOI2010]count 数字计数(数位dp)
- BZOJ 1833: [ZJOI2010]count 数字计数 数位DP,处理前导0
- bzoj 1833 count 数字计数 数位dp
- BZOJ 1833 count 数字计数 数位DP
- DirectX11(二)
- kaldi005 -- 构图
- iOS学习笔记-072.CALayer02——transform属性
- Java数据结构与算法---二叉树
- Android 资源管理
- BZOJ-1833 [ZJOI2010]count 数字计数 数位DP
- 快速排序
- 垃圾收集机制——JavaScript
- java可变参数
- APP 微信支付,服务端处理
- GCC的-fno-builtin选项
- 七层中反射+配置文件的使用
- hashmap与hashtable区别
- Javascript回调(一):简述