题目描述
给出平面上 $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(n\log 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\n" , ans); return 0; }