【贪心】POJ1328-Radar Installation

【思路】

以每一座岛屿为圆心,雷达范围为半径作圆,记录下与x轴的左右交点。如果与x轴没交点,则直接退出输出“-1”。以左交点为关键字进行排序,从左到右进行贪心。容易知道,离每一个雷达最远的那一座岛与雷达相距恰巧为半径的时候,可以得到最优解。假设上一个雷达与第before座岛相距为半径大小,对于当前的岛屿i:

如果before岛的右交点在i岛左交点的左侧,此时必然需要一个新的雷达,将当前before暂定为i,雷达数加一;

如果before岛的右交点在i岛右交点的右侧,为了让雷达举例尽可能地广,将雷达移至当前岛屿与x轴的交点上,将当前before暂定为i,雷达数不变。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 double sqrt(double n);
 7 struct rec
 8 {
 9     double left,right;
10     bool operator < (const rec& x) const
11     {
12         return left<x.left;
13     }
14 };
15 
16 const int MAXN=1000+5;
17 int n,d;
18 rec inter[MAXN];
19 
20 int calculate()
21 {
22     sort(inter,inter+n);
23     int ans=1;
24     int before=0;
25     for (int i=1;i<n;i++)
26     {
27         if (inter[before].right<inter[i].left)
28         {
29             ans++;
30             before=i;
31         }
32         else if (inter[before].right>=inter[i].right)
33         {
34             before=i;
35         }
36     }
37     return ans;
38 }
39 
40 int main()
41 {
42     int t=0;
43     while (scanf("%d%d",&n,&d))
44     {
45         if (n==d && d==0) break;
46         t++;
47         int f=1;
48         for (int i=0;i<n;i++)
49         {
50             double x,y;
51             cin>>x>>y;
52             if (d<y)
53             {
54                 f=0;    
55             }
56             else
57             {
58                 inter[i].left=x*1.0-sqrt(d*d-y*y);
59                 inter[i].right=x*1.0+sqrt(d*d-y*y);
60             }
61         }
62         cout<<"Case "<<t<<": ";
63         if (f) cout<<calculate()<<endl;else cout<<-1<<endl;
64             
65     }
66     return 0;
67 }
原文地址:https://www.cnblogs.com/iiyiyi/p/4690899.html