51Nod-1091 线段的重叠

51Nod 1091:  http://www.51nod.com/onlineJudge/questionCode.html#!problemId=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

 

 

题解:

求最长的重叠段的长度

利用sort之后的数组,进行O(N) 扫, 维护一个最远点end, 可以求得当前线段与已存在线段的最长重叠段。 

 

#include <iostream> 
#include <cstdio> 
#include <cstring> 
#include <algorithm>
#include <map> 
#include <cmath> 
using namespace std;

const int maxn = 50005; 

struct Segment{
	int x, y; 
}s[maxn]; 
int n; 

int cmp(const void *a, const void *b){
	Segment *aa = (Segment *)a; 
	Segment *bb = (Segment *)b; 
	if(aa->x == bb->x){
		return bb->y - aa->x; 
	}
	return aa->x - bb->x; 
}

int main(){
	freopen("in.txt", "r", stdin); 

	int len, j, ans, end; 
	while(scanf("%d", &n) != EOF){
		for(int i=0; i<n; ++i){
			scanf("%d %d", &s[i].x, &s[i].y ); 
		}
		qsort(s, n, sizeof(s[0]), cmp); 
		ans = 0;  end = s[0].y; 
		for(int i=0; i<n-1; ++i){
			ans = max(ans, min(end, s[i+1].y) - s[i+1].x); 
			end = max(end, s[i+1].y); 
		}
		printf("%d\n",  ans);
	}
	return 0; 
}

  

 

posted @ 2016-11-02 10:51  zhang--yd  阅读(394)  评论(0编辑  收藏  举报