51nod- 【1042 数字0-9的数量 】

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1042

题目:

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示例

1
11
1
1
1
1
1
1
1
1

题解:

求区间[a,b]各位数字出现次数并打印输出。因为数据是10^18,暴力会T。所以应该要找出出现的规律,优化算法。

从个位开始分析各个数位。不妨把当前数位右侧的数都当作0来统计:

1、当前数位(cur):那么当前数位从1开始到cur,当前数位每增大1,这个数字出现次数是当前数位的权值value(如从11增大到12时,个位上1出现了value = 1次;从110增大到120时,十位上的1出现了value = 10次)

2、当前数位左边的数(res)也会影响当前数位:res每增大1,当前数位的数都会从0-9走遍历一遍,其中每次遍历在0-9的每个数字上产生的次数为value次。(如12300这个数,res = 123 ,value = 10,十位上的0-9产生的总次数均为 res * value = 1230 次)

3、当前数位还会影响当前数位左边的数:当前数位从0开始到cur,当前数位每增大1,当前数位左边的每个数均出现value次,所以总共会出现value * (cur + 1)次。(如12340这个数,cur = 4,value = 10。从12300增大到12349时,cur左边的1、2、3这三个数均会出现 value * (cur + 1) = 50次)

4、如果当前数位左边还有数,当前数位左移,继续统计。

AC代码:
 1 #include <iostream>
 2 #include <cstring>
 3
 4 using namespace std;
 5 typedef long long ll;
 6
 7 void dfs(ll res , ll value , ll LLSum[])
 8 {
 9     ll cur = res % 10;
10     res /= 10;
11     ll t = res;
12     for (int i = 1 ; i <= cur ; i++) LLSum[i] += value;
13     for (int i = 0 ; i < 10 ; i++) LLSum[i] += res * value;
14     while (t) {
15         LLSum[t%10] += (cur + 1) * value;
16         t /= 10;
17     }
18     if (res) dfs(res-1,value * 10,LLSum);
19     return;
20 }
21
22 int main()
23 {
24     ll a,b;
25     ll Suma[10],Sumb[10];
26     memset(Suma,0,sizeof(Suma));
27     memset(Sumb,0,sizeof(Sumb));
28     cin >> a >> b;
29     dfs(a-1,1,Suma);
30     dfs(b,1,Sumb);
31     for (int i = 0 ; i < 10 ; i++) {
32         cout << Sumb[i] - Suma[i] << endl;
33     }
34     return 0;
35 }
其实只要撸清各位数字之间的影响就可以了。

然后似乎还有数位DP的解法,待我再去研究一下。

原文地址:https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/8312713.html

时间: 2024-11-01 11:25:58

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示例

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

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<

(数位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

1042 数字0-9的数量(非数位dp解法)

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 题意很明确,其实只要能求的到b的就可以.然后用val(b) - val(a-1)就能得出结果

输入一批整数,输出其中的最大值和最小值,输入数字0就结束循环。如下所示

import java.util.Scanner; /** * 输入一批整数,输出其中的最大值和最小值,输入数字0就结束循环.如*下所示 请输入一个整数(输入0结束):20 请输入一个整数(输入0结束):35 * 请输入一个整数(输入0结束):1 请输入一个整数(输入0结束):57 请输入一个整数(输入0结束):0 最大值是:57 最小值是:1 */ public class Max { public static void main(String[] args) { Scanner sc =

字符0,数字0,‘\0’,NULL

\0是一个转义字符,将字符0转义为数字0.

编程题:将数字0~5放入一个整型数组,并逆序输出数组

#include<stdio.h> void main() { int i,a[5]; for(i=0;i<5;i++)         /*给数组中元素赋值*/ a[i]=i; for(i=4;i>=0;i--)          /*逆序输出数组中元素值*/ printf("%3d",a[i]); printf("\n"); } 编程题:将数字0~5放入一个整型数组,并逆序输出数组,布布扣,bubuko.com

空暇时候思考2(&amp;#39;\0&amp;#39;等价于数字0还是字符0)

/********************************************************************** * * Copyright (c)2015,WK Studios * * Filename: A.h * * Compiler: GCC vc 6.0 * * Author:WK * * Time: 2015 6 7 * *******************************************************************