(数位DP)51NOD 1042 数字0-9的数量

给出一段区间a-b,统计这个区间内0-9出现的次数。

比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次。

输入

两个数a,b(1 <= a <= b <= 10^18)

输出

输出共10行,分别是0-9出现的次数

输入样例

10 19

输出样例

1
11
1
1
1
1
1
1
1
1

解:被这道题卡了好久。。。最后自己找了个数模拟了一边流程。举个例子简单说说:对于数5314,我们可以将它拆分为【5310-5314】【5300-5309】【5000-5299】【0-4999】(注意删去前置0)这几个区间计算,以此得出答案。
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <math.h>
 4
 5 long long num[2][10],res,a,b;
 6
 7 void func(long long *tmp,long long *p,long long power)
 8 {
 9     if (power == 1) res = 0;
10     int t = *tmp % 10;
11     if (*tmp == 0)
12     {
13         int n = log10((double)power);
14         power /= 10;
15         for (int i = 1; i < n; ++i) p[0] -= 9 * (power /= 10) * i;
16         p[0] -= n - 1;
17         return;
18     }
19     *tmp /= 10;
20     if (res == 0) t++;
21     long long v= (long long)log10((double)power) * power / 10 * t;
22     for (int i = 9; i >= t; --i) p[i] += v;
23     for (int i = 0; i < t; ++i) p[i] += power + v;
24     p[t] += res;
25     res += t * power;
26     func(tmp, p, power * 10);
27     return;
28 }
29 int main()
30 {
31     while (scanf_s("%lld%lld", &a, &b) != EOF)
32     {
33         memset(num, 0, sizeof num);
34         a--;
35         func(&a, num[0], 1);
36         func(&b, num[1], 1);
37         for (int i = 0; i < 10; ++i) printf("%lld\n", num[1][i] - num[0][i]);
38     }
39     return 0;
40 }
当然也可以分别计算0-9的个数,但我不想继续琢磨了。。。

原文地址:https://www.cnblogs.com/Ekalos-blog/p/10745817.html

时间: 2024-10-27 11:15:15

(数位DP)51NOD 1042 数字0-9的数量的相关文章

51nod 1042 数字0-9的数量 (数位dp、dfs、前导0)

1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 取消关注 给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次. Input 两个数a,b(1 <= a <= b <= 10^18) Output 输出共10行,分别是0-9出现的次数 Input示例 10 19 Output示例

51Nod 1042 数字0-9的数量(数位DP)

题意: 求[l,r]中数字0-9分别出现的次数,11算两次1 思路: 数位dp题解好难写,直接贴代码吧 dp[i]表示[0, 10^i-1]中出现j的次数(按i位补全前导0,显然0-9出现的次数是相同的) 最后再减去每一位出现的前导零即可 代码: #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<

CodeVS 1359 数字计数 51nod 1042 数字0-9的数量 Pascal

题目大意: 我的代码又臭又长,但是毕竟是我这个jr想了几天才推出的公式,看别的大神都写数位DP,所以我决定分享一下我的思路.我认为我的思路一向是最好理解的! 要分两种情况讨论: 1.0的情况.我们首先推出0~9中只有1个0,在0~99中有(1+(9*100*1))个0{第一位可以为1~9,第二位可以为0~9,0只可以放在后者,所以乘1},在0~999中有((1+(9*100*1))+(9*101*2))个0~6666为例,先算出0~999中0的个数,在算出1000~5999中0的个数,则为(10

数位dp——奏响数字数位的美妙乐章

数位dp:处理数字数位关系的一种dp方式. 一般的题目特征十分明显: 1.一般和数字本身有很大关系. 2.一般求数字在区间L,R中的一些信息 3.L,R一般很大,通常能达到long long级别. dp方式也比较有套路: 一般有三种方法: 本质上的相似之处,都是集中在处理"填数有无限制","填数无限制情况下的固定方案数","某些已经搜出来的固定方案数" 1.记忆化搜索(没用过) 是一种倒着记忆的方法. 2.递推(我基本都是这个方法) 正着递推出答

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是

bin巨的数(数位DP)

题目描述 作为ACM史上年度重量级人物,bin巨目前已经掌握了史上最NB的数,群巨快来仰慕!!我们定义这样一个数,它里面的每一个数字都是成双成对出现 的,but,如果这个数里面存在0那么这也是NB的数,比如11,122122,12035,当然,需要剔除那些首位是0的数.我们的目标就是计算一个区 间内bin巨有多少NB数! 输入 输入第一行包含一个整数T,表示接下来有T组数据. 下面T行,每行包含两个数l和r,表示这个区间. 数据范围:0<=l<=r<=10^18 输出 输出T行,每行一个

poj2282(数位dp)

题意:计算a-b中各个数字出现的个数: 解法:数位dp(思想都是先算1-b的个数,然后减掉1-a中的个数),1-9数字的计算和前边计算1的那一篇数位dp差不多,计算0时候要加一维表示前缀是否全是0: 代码: /****************************************************** * author:xiefubao *******************************************************/ #pragma comment

【数位DP】【P4127】[AHOI2009]同类分布

Description 给出两个数 \(a,~b\) 求出 \([a~,b]\) 中各位数字之和能整除原数的数的个数. Limitations \(1 \leq a,~b \leq 10^{18}\) Solution 考虑数位DP. 设数字 \(A = \sum_{i = 0}^k a_i \times 10^i\),其数字和 \(B = \sum_{i = 0}^k a_i\) 那么 \(A\) 满足条件即为 \(A \equiv 0 \pmod B\),根据同余的性质,可以将求和符号拆开:

HDU 3555 Bomb(数位DP)

Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors', 'Ro, Sham, Bo', and a host of other names) in order to make arbitrary decisions such as who gets