首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【51Nod】1042 - 数字0-9的数量(数位dp & 递归)

【51Nod】1042 - 数字0-9的数量(数位dp & 递归)

作者头像
FishWang
发布2025-08-27 10:11:41
发布2025-08-27 10:11:41
10700
代码可运行
举报
运行总次数: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

代码语言:javascript
代码运行次数:0
运行
复制
两个数a,b(1 <= a <= b <= 10^18)

Output

代码语言:javascript
代码运行次数:0
运行
复制
输出共10行,分别是0-9出现的次数

Input示例

代码语言:javascript
代码运行次数:0
运行
复制
10 19

以前有一个算数字1的个数,这两个挺像的,这个的递归思路基本上是模仿那个。

传送门:点击打开链接

看懂了那道题,再看这个。

虽然说思路差不多一样,但是我做这个的时候也是看了别人的题解的,因为绕进去确实有点晕。

每一个数字无非就三种影响关系:

①它对低位的影响

②它对高位的影响

③高位对低位的影响

然后在递归中实现这三种关系的计算即可:

代码:

代码语言:javascript
代码运行次数:0
运行
复制
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
void dp(LL n , LL m , LL *c)
{
	LL x = n % 10;
	LL y = n / 10;
	for (int i = 0 ; i <= x ; i++)
		c[i] += m;		//当前位对低位的影响,每个都是0~9的范围 
	for (int i = 0 ; i <= 9 ; i++)
		c[i] += m * y;		//当前位对的高位影响(高位不为0,在上一个循环中算过) 
	c[0] -= m;		//排除前导0的情况
	LL t = y;
	while (t)		//高位对低位的影响,即都为最大限制数 
	{
		c[t % 10] += (x+1) * m;		//算上0
		t /= 10; 
	}
	if (y)
		dp(y-1 , m*10 , c);		//y值在上个while中算过,算下一个未限制数 
}
int main()
{
	LL r,l;
	LL a[10] = {0};
	LL b[10] = {0};
	scanf ("%lld %lld",&l,&r);
	dp(r , 1 , a);
	dp(l-1 , 1 , b);
	for (int i = 0 ; i <= 9 ; i++)
		printf ("%lld\n",a[i]-b[i]);
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-08-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档