P1325雷达安装

 

 这道题我们看上去没有思路。但是当我们知道了岛屿的位置和雷达的扫描半径后,我们就可以求出要扫描到每个岛屿,雷达的安装范围。同时,根据贪心原理,很明显要把雷达尽量布置在海岸线上。这样,我们就将本题转化为了一道区间选点问题,只需要选择尽量少的点,满足每一个扫描区间内都有一个点即可。

下面分析代码。

首先,我们还是要先定义好岛屿个数n和雷达的扫描半径d,并设置一个cnt来记录最少的雷达数。

同时,我们来定义一个结构体来记录每一个岛屿所对应的雷达扫描区间。设置两个double变量l和r来标记边界。得到代码如下:

1 #include<iostream>
2 using namespace std;
3 int n,d,ans;
4 struct qujian{
5     double l,r;
6 }t[1005];
7 int main(){
8     return 0;
9 }

接下来,我们要进行读入。先读入岛屿树木n和雷达扫描半径d,然后从1到n依次读入每个岛屿的坐标。因为读入的并不是区间的左边界和右边界,所以我定义了两个整型变量a,b表示坐标(因为将该坐标转化为区间后,该坐标不再有作用,所以可以直接覆盖)。如果b>d,说明无论如何雷达也扫描不到该岛屿,则需要输出-1,并且直接return 0。否则,我们可以根据两点间距离公式得出区间的左边界l=a-sqrt(d*d-b*b);右边界r=a+sqrt(d*d-b*b)。得到代码如下:

 1 #include<iostream>
 2 using namespace std;
 3 int n,d,ans,a,b;
 4 double position;
 5 struct qujian{
 6     double l,r;
 7 }t[1005];
 8 int main(){
 9     cin>>n>>d;
10     for(i=1;i<=n;i++){ 
11         cin>>a>>b;
12         if(b>d){
13             cout<<-1<<endl;
14             return 0;
15         }
16         t[i].l=a-sqrt(d*d-b*b);
17         t[i].r=a+sqrt(d*d-b*b);
18     }
19     return 0;
20 }

接下来,我们便可以使用区间选点问题的处理方法进行计算。

首先,我们仍需要按照区间的右边界进行排序。这里仍然使用<algorithm>中的排序函数sort,并且需要手写cmp函数。注意函数的类型名为double。然后,我们需要将ans记录的雷达数初始化。
下一步,我们要枚举每一个区间。注意这里和一般的区间选点问题不同的是,区间的边界和雷达的安装都是double类型的,而且每个区间固定只需要安装一个点。所以我们只需要定义一个double类型的变量position,来记录当前的最靠右的雷达位置。

这里需要注意的是,在枚举每个岛屿时,第一个岛屿并不是从0点开始的,所以在初始化时,我们需要将r初始化为第一个节点的右边界,而非0,同时将ans初始化为1(默认第一个雷达安装在第一个岛屿右边界),并从2开始枚举安装雷达。

下面是本题的完整代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cmath>
 4 using namespace std;
 5 int n,d,ans,a,b,i;
 6 double position;
 7 struct qujian{
 8     double l,r;
 9 }t[1005];
10 double cmp(qujian a,qujian b){ 
11     return a.r<b.r;
12 }
13 int main(){
14     cin>>n>>d;
15     for(i=1;i<=n;i++){ 
16         cin>>a>>b;
17         if(b>d){
18             cout<<-1<<endl;
19             return 0;
20         }
21         t[i].l=a-sqrt(d*d-b*b);
22         t[i].r=a+sqrt(d*d-b*b);
23     }
24     sort(t+1,t+n+1,cmp);
25     ans=1;
26     position=t[1].r;
27     for(i=2;i<=n;i++){
28         if(position>=t[i].l){
29             continue;
30         }else{
31             ans++;
32             position=t[i].r;
33         }
34     }
35     cout<<ans<<endl;
36     return 0;
37 }
原文地址:https://www.cnblogs.com/qianr/p/13286991.html