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 ", ans); } return 0; }