|
import java.util.TreeMap; |
|
import java.util.Iterator; |
|
import java.util.Map; |
|
import java.util.Scanner; |
|
|
|
public class NTransmittersProblem { |
|
|
|
static int[] transCoord; |
|
static int[] transRange; |
|
/* This map will hold the start and end values of a particular point |
|
* true means some transmitter range starts at that point and false means range ends there |
|
*/ |
|
static TreeMap<Integer, Boolean> isStart = new TreeMap<Integer, Boolean>(); |
|
|
|
public static void main(String[] args) { |
|
Scanner sc = new Scanner(System.in); |
|
System.out.println("Enter the number of transmitters"); |
|
int n = sc.nextInt(); |
|
transCoord = new int[n]; |
|
System.out.println("Enter the coordinates and the range of the n transmitters"); |
|
transRange = new int[n]; |
|
for (int i = 0; i < n; i++) { |
|
transCoord[i] = sc.nextInt(); |
|
transRange[i] = sc.nextInt(); |
|
} |
|
sortArrayAndMaintainIndex(transCoord, transRange, 0, n-1); |
|
System.out.println("Enter the value of k"); |
|
int k = sc.nextInt(); |
|
fillHashMap(); |
|
System.out.println(getCountOfkRange(k)); |
|
} |
|
|
|
/* fills the map with thet start and end points of transmitter ranges*/ |
|
private static void fillHashMap() { |
|
for(int i = 0; i < transCoord.length; i++){ |
|
isStart.put(transCoord[i]-transRange[i], true); |
|
isStart.put(transCoord[i]+transRange[i], false); |
|
} |
|
} |
|
|
|
private static String getCountOfkRange(int k) { |
|
String op = ""; |
|
int count = 0, startIndex = 0, endIndex = 0; |
|
Iterator iterator = isStart.entrySet().iterator(); |
|
//hasStarted is a flag which is set to true if a habitable region has started |
|
boolean hasStarted = false; |
|
while(iterator.hasNext()){ |
|
Map.Entry entry = (Map.Entry)iterator.next(); |
|
if((boolean) entry.getValue()){ |
|
count++; |
|
if(count == k){ |
|
startIndex = (int)entry.getKey(); |
|
hasStarted = true; |
|
} |
|
} |
|
else{ |
|
count--; |
|
if(count == k-1 && hasStarted){ |
|
endIndex = (int)entry.getKey(); |
|
count++; |
|
hasStarted = false; |
|
} |
|
} |
|
if(count>=k && !hasStarted && endIndex > startIndex){ |
|
count--; |
|
op += startIndex + " to " + endIndex + ", "; |
|
} |
|
} |
|
|
|
return op; |
|
|
|
} |
|
|
|
/* uses quick sort |
|
* additional functionality is that 1-to-1 map between transCoord and transRange needs to be maintained |
|
* So with every swap of transCoord, corresponding swap of transRange needs to happen |
|
*/ |
|
private static void sortArrayAndMaintainIndex(int[] transCoord, int[] transRange, int lo, int hi) { |
|
if(hi-lo <= 1){ |
|
return; |
|
} |
|
int pivot = transCoord[hi]; |
|
int i = lo-1, temp; |
|
for(int x = lo; x < hi; x++){ |
|
if(transCoord[x] < pivot){ |
|
i++; |
|
temp = transCoord[i]; |
|
transCoord[i] = transCoord[x]; |
|
transCoord[x] = temp; |
|
|
|
temp = transRange[i]; |
|
transRange[i] = transRange[x]; |
|
transRange[x] = temp; |
|
} |
|
} |
|
i++; |
|
temp = transCoord[i]; |
|
transCoord[i] = transCoord[hi]; |
|
transCoord[hi] = temp; |
|
|
|
temp = transRange[i]; |
|
transRange[i] = transRange[hi]; |
|
transRange[hi] = temp; |
|
sortArrayAndMaintainIndex(transCoord, transRange, lo, i-1); |
|
sortArrayAndMaintainIndex(transCoord, transRange, i+1, hi); |
|
} |
|
|
|
} |