oj_贪心_#255. 安装雷达

题目描述

​ 地图 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;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值