UVA1616 with inclusion interval

Description

Lanran has N friends. Every Sunday, Lanran has to play with his friends. The i-th friend can play with Lanran from time a_iai​to time b_ibi​. However, Lanran has to play with each of his friends for the same amount of time.

Lanran wants to play with his friends as long as possible. But he is very stupid. So he asks for your help to calculate the maximum time he can play with each of his friends.

Input

The first line contains one integer N.

Each of the next N lines contains two integers a_iai​ and b_ibi​, which show the time interval of the i-th friend [a_i, b_i][ai​,bi​].

Output

Output a single integer, shows the maximum time Lanran can play with each of his friends.

Sample Input 1

3
1 10
5 9
7 11

Copy

Sample output 1

3

Copy

Sample Input 2

5
1 2
1 2
1 2
1 2
1 2

Copy

Sample output 2

0

Copy

Limit

1 second for each test case. The memory limit is 256MB.

For 60% test cases, the data is generated by random().

For 100% test cases, N \leq 5000, 1\leq a_i \leq b_i \leq 10000N≤5000,1≤ai​≤bi​≤10000. 

 

Solution

import java.io.*;

public class Main {
	public static void main(String[] args) throws Exception{
		//long b = System.currentTimeMillis();
		//InputStream fil = new FileInputStream(new File("C:\\Users\\ASUS\\desktop\\data.txt"));
		InputStream sys = System.in;
		StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(sys)));
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		in.nextToken(); 
		int N = (int)in.nval;
		int[] s = new int[N];
		int[] f = new int[N];
		int maxF = -1;
		int minT = Integer.MAX_VALUE;
		for (int n = 0; n < N; n++) {
			in.nextToken(); 
			s[n] = (int)in.nval;
			in.nextToken(); 
			f[n] = (int)in.nval;
			if(f[n] > maxF) maxF = f[n];
			if(f[n] - s[n] +1 < minT) minT = f[n] - s[n] + 1;
		}
		///Initialization
		mergeSort(s, f);
		boolean[] isOccupied  = new boolean[maxF+1];
		int       right       = minT;
		int       left        = 0;
		int       mid         = 0;
		boolean   notFit      = false;
		int       cnt         = 0;
		int       ans         = 0;
		///Binary Search
		while(left <= right) { //O(logI)
			//initialization
			mid = (right+left)/2;
			notFit = false;
			for(int i = 0; i < isOccupied.length; i++) isOccupied[i] = false;
			//
			for (int n = 0; n < N; n++) {// For all friend O(N)
				cnt = 0;
				for(int i = s[n]; i <=f[n]; i++) { // Find avalible time backward O(I)
					if(!isOccupied[i]) {
						cnt = cnt + 1;
						isOccupied[i] = true;
					}
					if(cnt == mid) {
						break;
					}
				}
				if(cnt < mid) {
					notFit = true;
					break;
				}
			}
			//Adjust boundary
			if(notFit) {
				right = mid - 1;
			}else {
				left = mid + 1;
				ans = mid;
			}
		}
		out.println(ans);
		//System.out.println(System.currentTimeMillis() - b +"ms");
		out.close();
	}
	/double atribute merge sort template/
	   public static void mergeSort(int[] A, int[] B){
	      mergeSort(A, B, new int[A.length], new int[A.length], 0, A.length-1);
	   }

	   public static void mergeSort(int[] A, int[] B, int[] tmpA, int[] tmpB, int left, int right){
	      if(left <right){
	         int center = (left+right) / 2;
	         mergeSort(A, B, tmpA, tmpB, left, center);
	         mergeSort(A, B, tmpA, tmpB, center+1, right);
	         merge(A, B, tmpA, tmpB, left, center+1, right);
	      }
	   }
	   public static void merge(int[] A, int[] B, int[] tmpA, int[] tmpB, int leftPos, int rightPos, int rightEnd){
	      int leftEnd = rightPos - 1;
	      int tmpPos = leftPos;
	      int num = rightEnd - leftPos + 1;
	      while(leftPos<=leftEnd && rightPos <= rightEnd){
	         if(B[leftPos] < B[rightPos]){
	            tmpB[tmpPos] = B[leftPos];
	            tmpA[tmpPos++] = A[leftPos++];
	         }else{
	            tmpB[tmpPos] = B[rightPos];
	            tmpA[tmpPos++] = A[rightPos++];
	         }
	      }
	      while(leftPos<=leftEnd){
	         tmpB[tmpPos] = B[leftPos];
	         tmpA[tmpPos++] = A[leftPos++];
	      }
	      while(rightPos<=rightEnd){
	         tmpB[tmpPos] = B[rightPos];
	         tmpA[tmpPos++] = A[rightPos++];
	      }
	      for(int i = 0; i < num; i++, rightEnd--){
	         A[rightEnd] = tmpA[rightEnd];
	         B[rightEnd] = tmpB[rightEnd];
	      }
	   }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值