zoukankan      html  css  js  c++  java
  • poj 1328 Radar Installation

    题意:

    在海上有很多的小岛,要建造一些雷达来把所有的小岛都覆盖掉。

    雷达只能建造在海岸线上(水平的X轴),且所有雷达的覆盖半径是相同的。

    现在问是否可以建造最少的雷达使得所有的小岛都被覆盖。

    思路:

    首先可以知道,如果一个小岛的纵坐标大于给定的半径,那么就不会存在合理的方案;

    对于一个小岛,可以通过半径计算出雷达的范围,每一个小岛就对应一个雷达的区间,之后就转化成了在X轴上找最少的点,使得所有的区间都被覆盖,又是经典的区间覆盖问题。

    要注意的一点是要把重复的小岛去掉,我用的是set解决的这个问题。

    对于所有的区间,按照右端点从小到大排序,如果右端点相同,那么按照左端点从小到大排序。之后从第一个区间(当前区间)开始,找到左端点小于等于当前区间的右端点的区间,这些区间都可被当前区间中的某个点覆盖;直到找到左端点大于当前区间的右端点,那么就把这个区间作为当前区间,答案加一,继续找。

    代码:

     1 #include <stdio.h>
     2 #include <set>
     3 #include <algorithm>
     4 #include <vector>
     5 #include <math.h>
     6 using namespace std;
     7 
     8 typedef pair<int,int> p;
     9 
    10 set<p> s;
    11 vector<p> g;
    12 
    13 const double eps = 1e-8;
    14 const int N = 1005;
    15 pair<double,double> a[N];
    16 
    17 bool cmp(pair<double,double> xx,pair<double,double> yy)
    18 {
    19     if (fabs(xx.second - yy.second) < eps) return xx.first < yy.first;
    20     return xx.second < yy.second;
    21 }
    22 
    23 int main()
    24 {
    25     int n,d;
    26     int kase = 0;
    27     
    28     while (scanf("%d%d",&n,&d) != EOF && n + d)
    29     {
    30         s.clear();
    31         g.clear();
    32         
    33         bool f = 0;
    34         
    35         for (int i = 0;i < n;i++)
    36         {
    37             int x,y;
    38             
    39             scanf("%d%d",&x,&y);
    40             
    41             s.insert(p(x,y));
    42             
    43             if (y > d) f = 1;
    44         }
    45         
    46         if (f)
    47         {
    48             printf("Case %d: -1
    ",++kase);
    49             continue;
    50         }
    51         
    52         set<p>::iterator it;
    53         
    54         for (it  = s.begin();it != s.end();++it)
    55         {
    56             g.push_back(*it);
    57         }
    58         
    59         int sz = g.size();
    60         
    61         for (int i = 0;i < sz;i++)
    62         {
    63             int x = g[i].first,y = g[i].second;
    64             
    65             a[i].first = 1.0 * x - sqrt(1.0 * d * d - 1.0 * y * y);
    66             a[i].second = 1.0 * x + sqrt(1.0 * d * d - 1.0 * y * y);
    67         }
    68         
    69         sort(a,a+sz,cmp);
    70         
    71         int ans = 1;
    72         
    73         //double dis = (a[0].second - a[0].first) / 2.0;
    74         double cur = a[0].second;
    75         
    76         for (int i = 1;i < sz;i++)
    77         {
    78             if (cur >= a[i].first) continue;
    79             else
    80             {
    81                 ans++;
    82                 cur = a[i].second;
    83             }
    84         }
    85         
    86         printf("Case %d: %d
    ",++kase,ans);
    87     }
    88     
    89     return 0;
    90 }
  • 相关阅读:
    poj1573
    poj2632
    poj2993 poj2996
    poj3295 构造法
    poj2965枚举
    poj1753 枚举
    poj942Paths on a Grid
    poj1019
    poj1321棋盘问题
    博客园访问量有些小,我就没有必要在复制一份了,博客园就这样吧,继续CSDN了。
  • 原文地址:https://www.cnblogs.com/kickit/p/8808138.html
Copyright © 2011-2022 走看看