【nowcoder 218049】数字串

本文讲解了如何处理含有前导零的数字字符串,通过枚举和检查子串来确定哪些在指定范围内的子串,涉及到去除前导零并考虑加一的情况。核心算法是利用`check`函数判断子串是否在给定数字区间内。

数字串

题目链接:nowcoder 218049

到牛客看:

——>点我跳转<——

题目大意

给你一个由数字字符组成的字符串,和两个数。
问你你能在字符串中截出一个子串,它形成的数字在两个数之间(包括这两个数)。
提出的数可以有前导 0。

思路

首先我们考虑没有前导 0 怎么做。

那就直接枚举每个位数符合的子串,然后匹配。
但是有前导 0,可能就会有一个看起来位数不符合,但是把前导 0 去掉之后又符合了的情况。

那就考虑把前导 0 去掉,然后得出如果匹配就不是加一而是加前导 0 的个数+1。(+1 是因为可以一个前导零都不要)

代码

#include<cstdio>
#include<cstring>

using namespace std;

char L[500001], R[500001], s[500001];
int n, Ln, Rn, ans;

bool check(int l, int r) {//判断是否在两个数之间
	if (r - l + 1 < Ln) return 0;//看长度就知道不符合
	if (r - l + 1 > Rn) return 0;
	if (r - l + 1 == Ln) {//位数相同才要比较,不然直接可以确定可以(下同)
		for (int i = l; i <= r; i++) {
			if (s[i] > L[i - l + 1]) break;
			if (s[i] < L[i - l + 1]) return 0;
		}
	}
	if (r - l + 1 == Rn) {
		for (int i = l; i <= r; i++) {
			if (s[i] < R[i - l + 1]) break;
			if (s[i] > R[i - l + 1]) return 0;
		}
	}
	return 1;
}

int main() {
	scanf("%s %s\n%s", L + 1, R + 1, s + 1);
	Ln = strlen(L + 1);
	Rn = strlen(R + 1);
	n = strlen(s + 1);
	
	int qdl = 0;
	for (int i = 1; i <= n; i++) {
		if (s[i] == '0') {//处理前导 0
			qdl++;
			continue;
		}
		for (int j = Ln; j <= Rn && j + i - 1 <= n; j++)
			ans += (qdl + 1) * check(i, i + j - 1);//前导 0 选多少个都可以,所以要乘上个数加一
		qdl = 0;//清空前导零个数
	}
	
	printf("%lld", ans);
	
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值