长 L L L米,宽 W W W米的草坪里装有 n n n个浇灌喷头。每个喷头都装在草坪中心线上(离两边各 W 2 \frac{W}{2} 2W米)。我们知道每个喷头的位置(离草坪中心线左端的距离),以及它能覆盖到的浇灌范围。
请问:如果要同时浇灌整块草坪,最少需要打开多少个喷头?
题解
首先需要将不能覆盖W宽的喷水装置除掉。
然后计算出每个喷水装置最远覆盖范围
D
=
l
+
r
2
−
(
w
2
)
2
D = l+\sqrt{r^2-(\frac{w}{2})^2}
D=l+r2−(2w)2
然后按照左端点从小到大排序。
遍历所有喷水装置,同时记录当前最左、最右距离。
#include <iostream>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <stdio.h>
using namespace std;
#define ll long long
const int maxn = 15005;
struct node {
double l, r;
}a[maxn];
inline bool cmp(node a, node b) {
return a.l < b.l;
}
int main(int argc, char const *argv[])
{
int T, n;
double L, w;
double l, r;
scanf("%d", &T);
int cnt;
while (T--) {
cnt = 0;
scanf("%d %lf %lf", &n, &L, &w);
for (int i = 0; i < n; i++) {
scanf("%lf %lf", &l, &r);
if (2*r < w) continue;
a[cnt].l = l-sqrt(r*r-w*w/4);
a[cnt].r = l+sqrt(r*r-w*w/4);
cnt++;
}
sort(a, a+cnt, cmp);
bool flag = true;
double last = 0;
int res = 0, i = 0;
while (last <= L) {
res++;
double s = last;
for (; i < cnt && a[i].l <= s; i++)
if (a[i].r > last) last = a[i].r;
if (s == last && s < l) {
flag = false;
break;
}
}
printf("%d\n", flag ? res : -1);
}
return 0;
}