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_iaito 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];
}
}
}