【bzoj5166】[HAOI2014]遥感监测 贪心

题目描述

给出平面上 $n$ 个圆,在x轴上选出尽可能少的点,使得每个圆中至少有一个点。求这个最小点数。

输入

第1行: N R 分别表示激光点的个数和射电望远镜能检测到的半径
第2~N+1行: Xi Yi 表示 激光点的坐标位置
1≤R≤50 1≤N≤100 -1000≤ Xi Yi ≤ 1000 | Yi | ≤ R
N,R, Xi Yi都是整数。数据之间有一个空格。

输出

最少需要安装的射电望远镜数。

样例输入

3 2
1 2
-3 1
2 1

样例输出

2


题解

贪心

求出圆与x轴的两个交点,那么这个圆能够包含的点的范围在这两个交点之间。问题转化为给出若干区间,选出最少的点,使得每个区间中都至少有一个点。

问题变成贪心傻逼题,按照左端点从小到大排序,贪心地需要选则选即可。

时间复杂度为排序的 $O(nlog n)$ 

#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
struct data
{
    double l , r;
    bool operator<(const data &a)const {return l < a.l;}
}a[110];
int main()
{
    int n , m , i , x , y , ans = 0;
    double pos = -1e9;
    scanf("%d%d" , &n , &m);
    for(i = 1 ; i <= n ; i ++ ) scanf("%d%d" , &x , &y) , a[i].l = x - sqrt(m * m - y * y) , a[i].r = x + sqrt(m * m - y * y);
    sort(a + 1 , a + n + 1);
    for(i = 1 ; i <= n ; i ++ )
    {
        if(pos < a[i].l) ans ++ , pos = a[i].r;
        else pos = min(pos , a[i].r);
    }
    printf("%d
" , ans);
    return 0;
}

 

原文地址:https://www.cnblogs.com/GXZlegend/p/8626646.html