• 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 }
  • 相关阅读:
    Eclipse SVN插件设置
    经典语录-每日积累-05
    Shell基础语法,运算符,循环和判断语句和设置启动参数
    iOS-Jenkins自动化打包集成
    App版本升级相关
    Java-数组和集合简单使用
    Java-内部类简单使用
    Callkit被拒
    Java-Finalize(GC)和类与类和接口之间的关系
    经典语录-每日积累-04
  • 原文地址:https://www.cnblogs.com/qianr/p/13286991.html
Copyright © 2020-2023  润新知