题目描述
地图 x
轴的上方为海,下方为陆地,海中有 n 个小岛,坐标分别为 (Xi,Yi)。有一种雷达,能探测到的范围为以 d
为半径的圆。问海岸线上至少造多少雷达可以把所有的小岛都处在探测范围内。注意雷达是建在海岸线上的,也就是x轴上的。
输入
第一行输入两个数 n,d
。(1≤n≤1000)
接下来 n
行,每行两个数代表小岛的坐标。(−1000≤Xi,Yi≤1000)
输出
输出一个数表示答案,无解时输出 −1
。
样例输入
3 2
1 2
-3 1
2 1
样例输出
2
数据规模与约定
时间限制:1 s
内存限制:256 M
100% 的数据保证 1≤n≤1000
思路:
算出以每个小岛为圆心、雷达半径为半径的圆与x轴的两个交点。然后按照小岛与x轴两交点中较小交点排序,以此顺序遍历小岛覆盖范围的sequence,如果当前小岛未被访问,雷达数加一,则在此小岛之后的小岛有落在此小岛覆盖范围内的都标记为访问过。
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class oj_setRadar {
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt(),d=scanner.nextInt();
int[][] pos=new int[n][];
for(int i=0;i<n;i++){
pos[i]=new int[2];
for(int j=0;j<2;j++){
pos[i][j]=scanner.nextInt();
}
}
MiniSumRadar miniSumRadar=new MiniSumRadar(pos,d);
System.out.println(miniSumRadar.solve());
scanner.close();
}
}
class MiniSumRadar{
int[][] pos;
int d;
int radar;
MiniSumRadar(int[][] pos,int d){
this.pos=pos;
this.d=d;
}
int solve(){
double[][] shadow=new double[pos.length][];
for(int i=0;i<shadow.length;i++){
shadow[i]=new double[2];
int a=pos[i][0],b=pos[i][1];
double delta=Math.sqrt(d*d-b*b);
if (delta<0) return -1;
shadow[i][0]=1+delta/a;
shadow[i][1]=1-delta/a;
}
Arrays.sort(shadow,new Comparator<double[]>(){
@Override
public int compare(double[] o1,double[] o2){
if(o1[0]>o2[0]) return 1;
else if(o1[0]<o2[0]) return -1;
return 0;
}
});
Boolean[] visited=new Boolean[shadow.length];
Arrays.fill(visited,false);
for(int i=0;i<shadow.length;i++){
if(!visited[i]){
radar++;
visited[i]=true;
for(int j=i+1;j<shadow.length;j++){
if ((shadow[j][0]<=shadow[i][1])) visited[j]=true;
}
}
}
return radar;
}
}