例三 喷水装置
长 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;
}
题解