这个点就是贪心策略中的区间选点问题。
把右端点从大到小排序, 左端点从小到大排序。
每次取区间右端点就可以了, 到不能覆盖的时候就ans++, 重新取点
ps:这道题不考虑精度也可以过
要着重复习一下区间相关问题了, 包括前面没有例题的知识点的部分
#include<cstdio>
#include<cmath>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
const int MAXN = 112345;
struct node
{
double l, r;
node(double l = 0, double r = 0) : l(l), r(r) {}
}a[MAXN];
double L, dis;
int n;
void add(int i, double x, double y)
{
double t = sqrt(dis * dis - y * y);
double l = x - t, r = x + t;
a[i] = node(l, r);
}
bool cmp(node a, node b)
{
if(a.r != b.r)
return a.r < b.r;
return a.l > b.l;
}
int main()
{
while(~scanf("%lf%lf%d", &L, &dis, &n))
{
REP(i, 0, n)
{
double x, y;
scanf("%lf%lf", &x, &y);
add(i, x, y);
}
sort(a, a + n, cmp);
int ans = 1;
double ma = a[0].r;
REP(i, 1, n)
if(a[i].l > ma)
{
ans++;
ma = a[i].r;
}
printf("%d
", ans);
}
return 0;
}