51Nod - 1091 线段的重叠

本文介绍了一种解决线段重叠问题的有效算法。通过将线段的起点按升序排列,终点按降序排列,进而求解最大重叠区间。文章提供了详细的实现思路与证明过程,附带完整代码。

题目链接:点击打开链接

题意:题目叙述的很清楚,给出一些线段,求最大的线段重叠。

题解:

起点按照升序,终点按降序排序,然后线性跑一遍,维护最大值,和最靠后的终点值。

证明为什么是对的:

因为是起点是升序的,所后一个起点一定比前一个大或者相等,并且按终点降序,那么较长的线段一定在最前面,例如1--5一定在1--10后面。

那么求重合部分时只需要那起点去减去当前点的终点和一直维护那个最靠后的终点的最小值,就能求出来。

不理解的画个图然后推一推就可以。

——————

   ———--- 

               ————

若这三个为线段,那么这就是排序后的结果,大家手推一下就知道了。=-=

看代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 550000;
struct node{
	int x;
	int y;
}a[maxn];
bool cmp(node a,node b){
	if(a.x == b.x)
		return a.y > b.y;
	else 
		return a.x < b.x;
}
int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0 ; i < n ; i ++){
		scanf("%d%d",&a[i].x,&a[i].y);
	}
	sort(a,a+n,cmp);
	int ed = a[0].y;
	int ans = 0 ;
	for(int i = 1 ; i < n ; i ++){
		ans = max(ans,min(a[i].y,ed) - a[i].x);
		ed = max(ed,a[i].y);
	}
	cout << ans << endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值