#L. 喷水装置

Source: UVa 10382

长 L 米,宽 W 米的草坪里装有 n 个浇灌喷头。每个喷头都装在草坪中心线上(离两边各 W​ /2米)。我们知道每个喷头的位置(离草坪中心线左端的距离),以及它能覆盖到的浇灌范围。

请问:如果要同时浇灌整块草坪,最少需要打开多少个喷头

输入格式

输入包含若干组测试数据。

第一行一个整数 T 表示数据组数;

每组数据的第一行是整数 n、L 和 W;

接下来的 n 行,每行包含两个整数,给出一个喷头的位置和浇灌半径(上面的示意图是样例输入第一组数据所描述的情况)。

输出格式

对每组测试数据输出一个数字,表示要浇灌整块草坪所需喷头数目的最小值。如果所有喷头都打开也不能浇灌整块草坪,则输出 −1。

样例

3
8 20 2
5 3
4 1
1 2
7 2
10 2
13 3
16 2
19 4
3 10 1
3 5
9 3
6 1
3 10 1
5 3
1 1
9 1
6
2
-1

算出每一个喷头的范围,然后按左端点排序,每一次找到一个区间最长满足且左端点落在并区间之间的区间人,如果无法区间完全覆盖直接-1

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 15010;
class Node {
public:double l;//区间左边
	  double r;//区间右边
};
bool cmp(Node a, Node b) {
	if (a.l != b.l) {
		return a.l < b.l;
	}
	else  if(a.r!=b.r){
		return a.r > b.r;
	};
};
int main() {
	int t, n,site,flag;double length, width,len=0,radius=0;
	Node* s = new Node[N];
	cin >> t;
	for (int i = 1; i <= t; i++) {
		cin >> n >> length >> width;
		double mid = width / 2;
		flag = 1;
		for (int j = 1; j <= n; j++) {
			cin >> site>> radius;
			if (radius >= mid) {
				len = sqrt(radius * radius - mid * mid);
				s[flag].l = site - len;
				s[flag].r = site + len;
				flag++;
			}
		};
		sort(s + 1, s + 1 + flag, cmp);//从小排序
		double left = 0;
		int res = 0,f=1;
		while (left < length) {
			double last = left;//用于保存开始的左端点
			res++;
			for (int i = 1; i <= flag; i++) {//找到一个最大值
				if (s[i].l <= last && s[i].r >= left) {
					left = s[i].r;
				};
			};
			if (left == last && left < length) {
				cout << -1 << endl;;
				f = 0;
				break;
			};
		};
		if (f) {
			cout << res << endl;
		};
	};
	return 0;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值