【日常学习】【其他算法】codevs3371 刮油漆题解

本文介绍了一个有趣的算法问题——刮油漆问题。通过分析油漆覆盖的区间,利用类似积木大赛的思路,提出了一种高效的解决方案,并提供了C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述 Description

小J有一把尺子。一天MPS闲得无聊,拿了一桶油漆,用刷子在上面刷了N下,刷第i次有一个正整数范围(ai,bi),表示从尺子的刻度ai刷到刻度bi。此时ai到bi这个区间里的油漆层数+1。

为了去掉这些油漆,小J找来了一把刀,每次可以从尺子的一个整数刻度刮到另一个整数刻度。每刮一刀都有一个力度,如力度为3时可以一次刮掉3层油漆。但不能损坏尺子。比如有2层油漆的地方就不能用力度3来刮。

小J想知道最少要刮多少次。

输入描述 Input Description

第一行,一个整数N

第2...N+1行,第i+1行两个整数ai,bi。

输出描述 Output Description

一行,最少刮多少次。

样例输入 Sample Input

3

1 4

2 5

1 5

样例输出 Sample Output

2

数据范围及提示 Data Size & Hint

【样例解释】

刮2刀,第一次刮区间(1,5),力度为2,第一次刮区间(2,4),力度为1。

【数据范围】

40%的数据N<=2000

100%的数据N,ai,bi<=10^5

乍一看似乎有些复杂,只是好像和“积木大赛”有点像?不同点在于积木大赛只能动一层,而这个可移动很多层。只要是连续区间即可。

于是按照积木大赛的算法改了一下,但是失败了···

但是和正确的算法也有异曲同工之妙 

事实上,我们只需要在读入每个区间时【对区间的左端点a[k]+1,右端点a[k]-1,最后统计是正数多还是负数多即可】

为什么这样可以呢?我们举一个例子:

第一个区间【1,3】

第二个区间【1,5】

那么图像是这样的

XXX

XXXXX

对应数字为

1 0 -1 0 -1

结合积木大赛的思路,由于负数有两个,有两处下降,那么至少两次才能刮完。更多情况,可以以此深入理解。


code

//codevs3371 刮油漆
//copyright by ametake
#include
#include
#include
using namespace std;

const int maxn=500000+10;
int p[maxn]; 
int n;

int main()
{
	scanf("%d",&n);
	int a,b;
	for (int i=1;i<=n;i++)
	{
		scanf("%d%d",&a,&b);
		p[a]++;
		p[b]--;
	}
	int po=0,ne=0;
	for (int i=1;i<=maxn-9;i++)
	{
		if (p[i]>0) po++;
		if (p[i]<0) ne++;
	}
	if (po>ne) printf("%d\n",po);
	else printf("%d\n",ne);
	return 0;
}

——泪随流水急,愁逐野云飞




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值