审题细节:直径小于宽的长度的数据不记录
覆盖范围是 x加减sqrt( r^2-(w/2)^2)
贪心策略:
预处理:我们把每个覆盖区间的边界记录,左端点小的排前
我们首先用一个left=0这个变量,然后我们去找每个覆盖区间左边界小于等于left的区间,并且找到一个区间最大的,然后更新left的值;继续向后查找
大致是这个意思,看代码的具体实现
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int W;
struct range
{
double l, r;
range() {}
range(int _x, int _r)
{
double r1 = sqrt(_r * _r - W * W / 4.0);
l = _x - r1;
r = _x + r1;
}
};
const int MAXN = 15005;
range p[MAXN];
inline bool cmp(range x, range y)
{
return x.l < y.l;
}
int main()
{
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++)
{
int n, L, l = 0, cnt = 0;
scanf("%d %d %d", &n, &L, &W);
for (int j = 0; j < n; j++)
{
int x, r;
scanf("%d %d", &x, &r);
if (r << 1 >= W)
p[l++] = range(x, r);
}
sort(p, p + l, cmp);
double left = 0;
for (int j = 0; j < l && left < L;)
{
double maxr = -1;
while (p[j].l <= left && j < l)
{
maxr = max(maxr, p[j].r);
j++;
}
if (maxr == -1)
{
cnt = -1;
break;
}
left = maxr;
cnt++;
}
printf("%d\n", cnt);
}
return 0;
}
这篇博客讲的很细节: #10002. 「一本通 1.1 例 3」喷水装置_TJ.的博客-CSDN博客