zoukankan      html  css  js  c++  java
  • C-C Radar Installation 解题报告

    C-C    Radar Installation   解题报告

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=86640#problem/C

    题目:

    Description

     
    Download as PDF
     

    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<tex2html_verbatim_mark> distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d<tex2html_verbatim_mark>     .     

    We use Cartesian coordinate system, defining the coasting is the x<tex2html_verbatim_mark>    -axis. The sea side is above x<tex2html_verbatim_mark>     -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<tex2html_verbatim_mark>      -       y<tex2html_verbatim_mark> coordinates.       

     

    epsfbox{p2519.eps}<tex2html_verbatim_mark>

    Input

    The input consists of several test cases. The first line of each case contains two integers n<tex2html_verbatim_mark>(1$ le$n$ le$1000)<tex2html_verbatim_mark> and d<tex2html_verbatim_mark>      , where n<tex2html_verbatim_mark> is the number of islands in the sea and d<tex2html_verbatim_mark> is the distance of coverage of the radar installation. This is followed by n<tex2html_verbatim_mark> 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
    
    题目大意:
    在一条海岸线的一侧有若干个岛屿,将海岸线看成是X轴,X轴以上是大海,在海岸上安装雷达使其能覆盖全部岛屿,给出雷达的覆盖半径和岛屿位置,求最少使用多少
    雷达才能将所有岛屿全部覆盖。无法覆盖输出-1.


    分析:
    1.可以换一种想法,求雷达覆盖小岛就是以小岛为圆心,雷达的覆盖半径为半径画圆
    2.小岛到海岸线的距离大于半径,不能覆盖所有小岛,输出-1
    3.若小于半径,该圆与X轴的左交点为line[i].l=(double)x-sqrt((double)d*d-y*y);右交点为 line[i].r=(double)x+sqrt((double)d*d-y*y);
    4.将左交点排序,判断雷达位置,如果i点的左交点在当前雷达的右边,需要安装一个新雷达;如果i点的右交点在当前雷达的左边,则把当前雷达的圆心更新为该点的右交点

    代码:
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 const int maxn=1005;
     8 
     9 struct Line  //每个岛作半径为d的圆,与x轴所截的线段
    10 {
    11     double l,r;
    12 }line[maxn];
    13 
    14 bool cmp(Line a,Line b)//按照线段的左端点从小到大排序
    15 {
    16     return a.l<b.l;
    17 }
    18 
    19 int main()
    20 {
    21     int n,d;
    22     int i;
    23     int x,y;
    24     bool yes;//确定是不是有解
    25     int m=1;
    26     while(scanf("%d%d",&n,&d)!=EOF)
    27     {
    28         yes=true;
    29         int cnt=0;
    30         if(n==0&&d==0)  //n,d均为0,程序结束
    31             break;
    32         for(i=0;i<n;i++)
    33         {
    34             scanf("%d%d",&x,&y);
    35             if(yes==false)
    36                 continue;
    37             if(y>d)
    38                 yes=false;
    39             else
    40             {
    41                 line[i].l=(double)x-sqrt((double)d*d-y*y);
    42                 line[i].r=(double)x+sqrt((double)d*d-y*y);
    43             }
    44         }
    45         if(yes==false)  //不能完全覆盖
    46         {
    47             printf("Case %d: -1
    ",m++);
    48             continue;
    49         }
    50         sort(line,line+n,cmp);//排序
    51         cnt++;
    52         double now=line[0].r;
    53         for(i=1;i<n;i++)
    54         {
    55             if(line[i].r<now)  //与现在比较,这个很重要
    56                 now=line[i].r;
    57             else if(now<line[i].l)
    58             {
    59                 now=line[i].r;
    60                 cnt++;
    61             }        
    62         }
    63         printf("Case %d: %d
    ",m++,cnt);
    64     }
    65     
    66     return 0;
    67 }
    View Code


     

  • 相关阅读:
    2020年4月4日训练
    HZNU Training 17 for Zhejiang Provincial Competition 2020
    [kuangbin带你飞]专题四 最短路练习
    三分法
    洛谷多校第一周续
    洛谷春季 ACM 多校训练第五周
    简单数学三月小结
    线段树&树状数组
    图论三月小结
    Java中Double保留后小数位的几种方法
  • 原文地址:https://www.cnblogs.com/ttmj865/p/4716470.html
Copyright © 2011-2022 走看看