AcWing 112. 雷达设备 解题思路及代码

先贴个题目:

以及原题链接: 112. 雷达设备 - AcWing题库icon-default.png?t=N7T8https://www.acwing.com/problem/content/114/

 这题如果直接枚举点肯定是不行的,但可以把每个小岛的可能雷达设置点抽象成x轴上的线段进行贪心,我们的选点尽量选在线段的重合处即可保证数量最少,这里有两个思路的小不同,在对线段进行排序的时候是根据左端点排序还是右端点排序?

我们注意到如果要设立一个新的雷达点,应该尽量在该线段的右端,那如果根据左端点排序,可能出现左端点很小右端点很大的情况,导致这个右端点其实不是最优解,所以依据右端点排序,枚举后判断左端点是否比他小即可,如果想根据左端点排序,每次应该取两次比较的线段的右端最小值作为设置雷达的判断。

代码如下:

依据左端点排序:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

typedef pair<double,double> PDD;
#define x first
#define y second

const int N=1010;

PDD list[N];

int main()
{
    int n,d;
    cin>>n>>d;
    bool sign=true;
    for(int i=0;i<n;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        if(y>d)
        {
            sign=false;
            break;
        }
        double dx=sqrt(d*d-y*y);
        list[i].x=x-dx;
        list[i].y=x+dx;
    }
    if(!sign)
    {
        cout<<"-1";
        return 0;
    }
    sort(list,list+n);
   // for(int i=0;i<n;++i)
        //printf("%lf %lf\n",list[i].x,list[i].y);
    double s=list[0].y;
    int ans=1;
    for(int i=1;i<n;++i)
    {
        if(s>=list[i].x)
        {
            s=min(s,list[i].y);
        }
        else
        {
            //cout<<ans<<" "<<s<<" "<<list[i].y<<endl;
            ans++;
            s=list[i].y;
        }
    }
    cout<<ans;
    return 0;
}

依据右端点排序:

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

typedef pair<double, double> PDD;
#define l second
#define r first

const int N = 1010;

PDD list[N];

int main()
{
    int n, d;
    cin >> n >> d;
    bool sign = true;
    for (int i = 0; i < n; ++i)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        if (y > d)
        {
            sign = false;
            break;
        }
        double dx = sqrt(d * d - y * y);
        list[i].l = x - dx;
        list[i].r = x + dx;
    }
    if (!sign)
    {
        cout << -1;
        return 0;
    }
    sort(list, list + n);
    double s = list[0].r;
    int ans = 1;
    for (int i = 1; i < n; ++i)
    {
        if (s >= list[i].l)
            continue;
        else
        {
            ans++;
            s = list[i].r;
        }
    }
    cout << ans;
    return 0;
}

by————2024.4.9刷题记录

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值