51nod 1091 线段重叠(贪心

本文介绍了一种解决寻找两条线段最长重叠部分的方法,通过贪心算法对线段的起点和终点进行排序,最终输出最长重叠区间长度。

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

X轴上有N条线段,每条线段包括1个起点和终点。线段的重叠是这样来算的,[10 20]和[12 25]的重叠部分为[12 20]。
给出N条线段的起点和终点,从中选出2条线段,这两条线段的重叠部分是最长的。输出这个最长的距离。如果没有重叠,输出0。

Input
第1行:线段的数量N(2 <= N <= 50000)。
第2 - N + 1行:每行2个数,线段的起点和终点。(0 <= s , e <= 10^9)

Output
输出最长重复区间的长度。

Input示例
5
1 5
2 4
2 8
3 7
7 9

Output示例
4

思路:
一眼就知道是贪心,要对开始和结束进行排序,开始坑定是升序的排序,降序直接就降序排序,之前交了两遍,两个for不管怎么优化,第16组wa了(不懂为什么),最后四组超限。反正我也只是用(n^2)的算法去测试一下测试数据~
反思:用两个for一个存放被比较的线段,一个存放当前线段,这样写会超时,现在想一下可不可以优化一下。其实正真需要的是被比较线段的结尾,开头并不需要,因为经过排序,所有的开头都在这个开头的后面。结尾呢,真正需要的是一个比较远的位置(在这个部分,开始的排序就比较重要了,因为所有的起点都是按升序排序的,下一段的起点不可能包含上一段的起点!!![这个部分非常重要])到这里就可以把一个for循环优化成一个标记数字了,前i-1个点当中结束为主最远的点。

代码讲解:

 #include<iostream>
 #include<algorithm>
 using namespace std;

 struct segment{
    int s, e;
 }se[50100]; 

 bool cmp(segment a, segment b){
    if(a.s != b.s) return a.s < b.s;
    else return a.e > b.e; 
 }

 int main(){
    int t;
    cin >> t;
    for(int i = 0; i < t; i++)
      cin >> se[i].s >> se[i].e;
    sort(se,se+t,cmp);
    int e = se[0].e, maxn = 0;//e为那个标记,前i-1个线段最远的结束位置
    for(int i = 1; i < t; i++){
        if(se[i].e > e) maxn = max(maxn , e - se[i].s) , e = se[i].e;//先找到重叠的线段,再更新下标
        else maxn = max(maxn , se[i].e - se[i].s); 
    }
    cout << maxn << endl; 
    return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值