Segment

Segment

Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)

Total Submission(s) : 5   Accepted Submission(s) : 2

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

They are N segments in x-axis. Each segment has a start point X, an end point Y, so it can be expressed as [X, Y].
Now you should select two segments, and they have the longest overlap length.
For example, segment [3, 10] and segment [7, 12] overlap in [7, 10], so the length is 3.

Input

The first line is case number T ( T <= 10 ).
For each case, the first line is the segment number N ( 1 <= N <= 100,000 ). Following there are N lines, and each line contians Xi and Yi. ( 0 <= Xi < Yi < 100,000 )

Output

The longest overlap length of any two segments.

Sample Input

1

5

1 5

2 4

2 8

3 7

7 9

 

Sample Output

4


题意:从所给的线段中,找出两个线段相交的最大长度

思路:先把所有线段按照起点从小到大进行排序,然后维护一个在当前线段以前线段的终点的最大值,然后在当前线段的终点与前面维护的值中取一个最小值,减去当前线段的起点,就是当前线段和前面线段能够覆盖的最大长度了,然后对于对于每个线段求这个长度,最后再取其中最大的


代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
#define max(a ,b) a>b?a:b
#define min(a ,b) a<b?a:b
#define INF 1000005
#define PI atan(1.0)*4.0
#define N 100005
struct node{
	int u ,v;
	bool operator <(const node &s)const
	{
		return u < s.u;
	}
}a[N];
int main()
{
    freopen("in.txt" ,"r" ,stdin);
    freopen("out.txt" ,"w" ,stdout);
    int t;
    scanf("%d" ,&t);
    while(t--)
    {
    	int n;
    	scanf("%d",&n);
    	for(int i = 0 ; i < n;  i++)
    	{
    		scanf("%d%d" ,&a[i].u , &a[i].v);
    	}
    	sort(a ,a+n);
    	//for(int i = 0 ; i < n ; i++)
    		//printf("%d %d\n" ,a[i].u ,a[i].v);
    	int max = 0;
    	int p = 1;
    	for(int i = 0 ; p < n ; i++ , p = i+1)
    	{
    		if(a[i].v - a[i].u < max)
    			continue;
    		while(p < n)
    		{
    			if(a[p].u > a[i].v)//后面线段的起点比第I条线段的终点还要长就直接结束判断
    				break;
    			if(a[p].v - a[p].u < max)//后面线段的长度比已知的最长长度还要短就直接跳过,判断下一条线段
    			{
    				p++;
    				continue;
    			}
    			else if(a[p].v < a[i].v)//后面线段的终点比第I条线段的终点要小就更新最长长度
    			{
    				max = a[p].v - a[p].u;
    			}
    			else//若前面条件都不符合,则判断后面线段的起点到第I条线段的终点是否比已知最长长度要大
    			{
    				int tmp = a[i].v - a[p].u;
    				if(tmp > max)
    				{
    					max = tmp;
    				}
    			}
    			p++;
    		}
    	}
    	printf("%d\n" ,max);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值