zoukankan      html  css  js  c++  java
  • 【贪心】Radar Installation(POJ1328)

    Description

    Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d.

    We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates.

    Figure A Sample Input of Radar Installations

    Input

    The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases.

    The input is terminated by a line containing pair of zeros

    Output

    For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. "-1" installation means no solution for that case.

    Sample Input

    3 2
    1 2
    -3 1
    2 1
    
    1 2
    0 2
    
    0 0
    

    Sample Output

    Case 1: 2
    Case 2: 1
    

    分析

    刚开始我是对雷达分析,不能想出全部覆盖小岛的方法,所以改对小岛分析,小岛是必须被覆盖的,所以可以得到覆盖小岛的雷达的横坐标最小值和最大值,然后按横坐标最大值从小到大排序,运用贪心算法,在横坐标最小值处放雷达,雷达就可以尽可能多的覆盖小岛。还有两个特殊情况:

    ①小岛y坐标大于雷达覆盖半径的话,就要输出-1。

    ②当横坐标最大值相同时,应让半径小的排在前,因为要在横坐标最小值处放雷达,这样可以保证横坐标最大值相同时都可以覆盖到。

    参考代码

    //这是我写的,大多数样例都过了,但是一直WA,T.T

    #include <iostream>
    #include <cstdio>
    #include <math.h>
    #include <algorithm>
    using namespace std;
    
    struct  P{
        double l;
        double r;
        }p[1001];
    
    bool compare(const P& a,const P& b);
    int main()
    {
        int sum=1;
        int n;
        double d;
        double x,y;
        int maxy=0;
        int num=1;
        while(1){
            maxy=0;
            sum=1;
           scanf("%d%lf",&n,&d);
           if(n==0&&d==0)
            break;
           for(int i=0;i<n;i++){
            scanf("%lf%lf",&x,&y);
            if(y>maxy){
                maxy=y;
            }
            double t=sqrt(d*d-y*y);
            p[i].l=x-t;
            p[i].r=x+t;
           }
    
           if(maxy>d){
            printf("Case %d: -1
    ",num++);
           }
    
           sort(p,p+n,compare);
           int minx=p[0].r;
           for(int i=1;i<n;i++){
                if(minx<p[i].l){
                    sum++;
                    minx=p[i].r;
                }
    
           }
           if(maxy<=d)
           printf("Case %d: %d
    ",num++,sum);
        }
    
    
    
        return 0;
    }
    bool compare(const P& a,const P& b){
        if(a.r==b.r)
            return a.l>b.l;
        return a.r<b.r;
    }

    //AC代码摘自http://www.cnblogs.com/q-c-y/p/4713557.html

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    #define MAX 1005
    using namespace std;
    struct note{
        double left,right;
    }b[MAX];
    double cmp(note a,note b)      //结构体排序
    {
        if(a.right==b.right) return a.left>b.left; 
            else
        return a.right<b.right;
    }
    int acount,n; 
    void search(double maxn)      //找到最少的雷达数
    {
        int i;
        for(i=1;i<n;i++)
            if(b[i].left>maxn)
            {
                maxn=b[i].right;        //都取最右端
                acount++;
            }
    }
    int main()
    {
        double d,x,y;
        scanf("%d%lf",&n,&d);
        int t=0;
        while(n||d)
        {
            t++;
            int o=0;
            acount=0;
            for(int i=0;i<n;i++)
            {
                scanf("%lf%lf",&x,&y);
                if(y>d)                      //判断是否可以扫射到岛
                    o++;
                b[i].left=x-sqrt((d*d)-(y*y));         //预处理,变成区间
                b[i].right=x+sqrt((d*d)-(y*y));
            }
            if(!o)
            {
                sort(b,b+n,cmp);
                search(b[0].right);
                printf("Case %d: %d
    ",t,acount+1);
            }
            else
                printf("Case %d: -1
    ",t);
            scanf("%d%lf",&n,&d);
        }
        return 0;
    }

     

     

     

     

  • 相关阅读:
    [LeetCode] 216. 组合总和 III
    [LeetCode] 215. 数组中的第K个最大元素
    [LeetCode] 215. 数组中的第K个最大元素
    [LeetCode] 215. 数组中的第K个最大元素
    [LeetCode] 213. 打家劫舍 II
    [LeetCode] 212. 单词搜索 II
    [LeetCode] 211. 添加与搜索单词
    转:十大编程算法助程序员走上高手之路
    推荐用于格式化以及高亮显示SQL文的PHP类-SqlFormatter
    转:实用 .htaccess 用法大全
  • 原文地址:https://www.cnblogs.com/LuRenJiang/p/7464670.html
Copyright © 2011-2022 走看看