喷水装置

题目描述

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

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

Picture1

输入格式

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

第一行一个整数 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

数据范围与提示

对于 100% 的数据,n≤15000

我本来是不太想用csdn的,它有的时候字输入不上去。但是我至今还没转博客园就是csdn实在是太好看啦 !

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int T;
struct node{
	double x,y;
}a[20005];//数组再一次的开小了。。。
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		int n,l,w;
		scanf("%d%d%d",&n,&l,&w);
		int cnt = 0;
		for(int i = 1;i <= n;i++)
		{
			int p,q;
			scanf("%d%d",&p,&q);
			if(2 * q <= w)continue;
			cnt++;
			a[cnt].x = p - sqrt(q * q - w * w/4.0);
			a[cnt].y = p + sqrt(q * q - w * w/4.0);
		}
		double t = 0;
		int ans = 0,flag = 0;
		while(t < l)//在所有左端点小于上一个区间右端点的线段中选择右端点最大的一个 
		{
			ans++;
			double s = t;
			for(int i = 1;i <= cnt;i++)
			{
				if(a[i].x <= s&&t < a[i].y)t = a[i].y;	
			}
			if(t == s && s < l){//如果找不到两个区域之间断开了或者所有区域长度之和小于规定长度就输出-1 
				printf("-1\n");
				flag = 1;
				break;
			}
		}
		if(flag == 0)printf("%d\n",ans); 
	}
	return 0;
}

这就是今日的贪心份额

猜你喜欢

转载自blog.csdn.net/qq_42914224/article/details/82466710