例三 喷水装置

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

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

输入格式

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

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

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

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

输出格式

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

 

#include<bits/stdc++.h>
using namespace std;
const int N=15010;
struct node{
	double l;
	double r;
	
}a[N];
int t;
int n,l,w;
bool cmp(node a,node b){
	return a.l<b.l;
}
int ans;
int main(){
	cin>>t;
	while(t--){
		ans=0;//初始化
		int m=0;
		cin>>n>>l>>w;
		for(int i=1;i<=n;i++){
			int b,c;
			cin>>b>>c;
			if(c*2<w){
				continue;//如果宽够不上那么肯定不会被覆盖
			}
			else{
				a[m].l=b-sqrt(c*c-w*w/4.0);
				a[m].r=b+sqrt(c*c-w*w/4.0);
				m++;
				
			}
		}
		sort(a,a+m,cmp);
		//排序
		double t=0;
		int i=0;
		int flag=1;
		//接下来就是判断过程
		while(t<l){
			ans++;
			double s=t;
			while(a[i].l<=s&&i<m){//这里就是判断是否一个花洒可以洒的范围包含了替他的花洒
				if(t<a[i].r){
					t=a[i].r;
				}
				i++;
			}
			if(t==s&&s<l){
				cout<<-1<<endl;
				flag=0;
				
				break;
			}
		}
		if(flag)
		cout<<ans<<endl;
	}
	return 0;
	
}

 题解

posted @ 2023-04-27 10:39  du463  阅读(8)  评论(0编辑  收藏  举报  来源