LibreOJ_10002

链接

思路

参考博客:喷水装置_贪心算法

首先计算出每个洒水器与草坪上下边界的交点的横坐标 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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值