链接
思路
参考博客:喷水装置_贪心算法
首先计算出每个洒水器与草坪上下边界的交点的横坐标 l l l 和 r r r 。
按照 l l l 升序排列, l l l 相同时按照 r r r 降序排列。
然后按照排好序的顺序遍历,维护最大右边界。
代码
// #pragma GCC optimize(3)
#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <deque>
#include <string>
#include <cstdio>
#include <bitset>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#define endl '\n'
#define x first
#define y second
#define fi first
#define se second
#define PI acos(-1)
// #define PI 3.1415926
#define LL long long
#define INF 0x3f3f3f3f
#define lowbit(x) (-x&x)
#define PII pair<int, int>
#define ULL unsigned long long
#define PIL pair<int, long long>
#define all(x) x.begin(), x.end()
#define mem(a, b) memset(a, b, sizeof a)
#define rev(x) reverse(x.begin(), x.end())
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int N = 15010;
struct Data {
double l, r;
}da[N];
int n;
double L, W;
bool cmp(Data a, Data b) {
if (a.l == b.l) return a.r > b.r;
return a.l < b.l;
}
void solve() {
int tt;
cin >> tt;
while (tt -- ) {
mem(da, 0);
cin >> n >> L >> W;
for (int i = 0; i < n; i ++ ) {
double x, r, t = 0;
cin >> x >> r;
if (r > W / 2) t = sqrt(pow(r, 2) - pow(W / 2, 2));
da[i] = {x - t, x + t};
}
sort(da, da + n, cmp);
int count = 0;
double start = 0, last = -1e18;
for (int i = 0; i < n && start < L; i ++ ) {
while (i < n && da[i].l <= start) {
last = max(last, da[i].r);
i ++ ;
}
count ++ ;
start = last;
if (i == n || da[i].l <= start) i -- ;
}
cout << (start >= L ? count : -1) << endl;
}
}
int main() {
IOS;
solve();
return 0;
}