• 51Nod 1091:线段的重叠(贪心)


                                        1091 线段的重叠 

    基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题

     收藏

     关注

    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

    思路

    有两种写法,但是思路都是差不多的,不同的是排序的方法有点区别

    1. 按照区间起点升序排序,如果起点相同,按终点升序排序。用一个数n记录排序后第一个区间的终点,然后对后面n-1个区间进行比较。如果第i个区间的终点小于k,那么区间覆盖的长度为第i个的终点减去起点,此时k值不变。如果第i个区间的终点大于k,那么区间覆盖的长度为k减去第i个区间的起点,并把k值更新为第i个区间的终点。记录下此时区间覆盖长度的最大值
    2. 按照区间起点升序排序,如果起点相同,按终点降序排序。用两个数s,e记录第一个区间的起点和终点。每次进行过一个区间,如果e小于区间的终点,更新s,e的值。(和上一种写法基本上是一样的,对于s,e的更新也是和上面k的更新条件一样,唯一不同的就是排序方式)。

    AC代码

    第一种

    #include<bits/stdc++.h>
    using namespace std;
    struct wzy{
    	int begin,end;
    }p[50000+10];
    bool cmp(wzy u,wzy v)
    {
    	if(u.begin==v.begin) 
    		return u.end<v.end;
    	else 
    		return u.begin<v.begin;
    }
    int main()
    {
    	int n,i,k;
    	int maxn=0;
    	cin>>n;
    	for(i=0;i<n;i++) 
    		cin>>p[i].begin>>p[i].end;
    	sort(p,p+n,cmp);
    	for(i=1,k=p[0].end;i<n;i++)
    	{
    		if(p[i].end>=k)
    		{
    			maxn=max(maxn,k-p[i].begin);
    			k=p[i].end;
    		}
    		else
    		{
    			maxn=max(maxn,p[i].end-p[i].begin);
    		}
    	}
    	cout<<maxn<<endl;
    	return 0;
    }

    第二种

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    #include <limits.h>
    #include <map>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <set>
    #include <string>
    #define ll long long
    #define ms(a) memset(a,0,sizeof(a))
    #define pi acos(-1.0)
    #define INF 0x3f3f3f3f
    const double E=exp(1);
    const int maxn=1e6+10;
    using namespace std;
    struct wzy
    {
    	int first,end;
    }p[maxn];
    bool cmp(wzy u,wzy v)
    {
    	if(u.first==v.first)
    		return u.end>v.end;
    	return u.first<v.first;
    }
    int main(int argc, char const *argv[])
    {
    	ios::sync_with_stdio(false);
    	int n;
    	cin>>n;
    	for(int i=0;i<n;i++)
    	{
    		cin>>p[i].first>>p[i].end;
    	}
    	sort(p,p+n,cmp);
    	for(int i=0;i<n;i++)
    		cout<<p[i].first<<"==========="<<p[i].end<<endl;
    	int ans;
    	int _=0;
    	int s=p[0].first,e=p[0].end;
    	for(int i=1;i<n;i++)
    	{
    		if(s<=p[i].first&&e<p[i].end)
    			ans=e-p[i].first;
    		else if(s<=p[i].first&&e>=p[i].end)
    			ans=p[i].end-p[i].first;
    		_=max(ans,_);
    		if(e>=p[i].end)
    			continue;
    		s=p[i].first;
    		e=p[i].end;
    	}
    	cout<<_<<endl;
    	return 0;
    }
    
  • 相关阅读:
    [poj 1741]Tree 点分治
    [bzoj 3251]树上三角形
    [bzoj 3687]简单题 bitset的运用
    HDU [P5015] 233 Matrix
    POJ 3233
    洛谷 [P3629] 巡逻
    POJ 2728 Desert King
    洛谷 [P2886] 牛继电器Cow Relays
    POJ 1734 Sightseeing trip
    洛谷 [P3008] 道路与航线
  • 原文地址:https://www.cnblogs.com/Friends-A/p/10324424.html
Copyright © 2020-2023  润新知