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\n",++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\n",++kase,ans);
87     }
88     
89     return 0;
90 }

 

posted @ 2018-04-12 15:39  qrfkickit  阅读(225)  评论(0编辑  收藏  举报