题意:在一条线段上选出尽量少的点,使得和所有给出的n个点距离不超过D。
分别计算出每个点在线段的满足条件的区间,然后就转化成了区间选点的问题了,按照右端点排序,相同时按照左端点排序,按照之前的排序一定保证了包含这个点的区间是连续的。贪心,每次选右边的端点,维护一个当前选择点的位置,每遇到区间就判断一下并更新一下点的位置。
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5+5; struct seg { double l,r; bool operator < (const seg& x) const{ return r < x.r || (r == x.r && l > x.l); } }S[maxn]; int main() { int L,D,N; while(~scanf("%d%d%d",&L,&D,&N)){ double dis = D; for(int i = 0; i < N; i++){ double x,y; scanf("%lf%lf",&x,&y); double r = sqrt(dis*dis-y*y); S[i].l = x-r; S[i].r = x+r; } sort(S,S+N); double cur = -1e9; int ans = 0; for(int i = 0; i < N; i++){ if(cur < S[i].l) { cur = S[i].r < L ?S[i].r : L; ans++; } } printf("%d ",ans); } return 0; }