喷水装置
链接:https://ac.nowcoder.com/acm/contest/950/C
来源:牛客网
长L米,宽W米的草坪里装有n个浇灌喷头。每个喷头都装在草坪中心线上(离两边各 \frac{W}{2} 2W 米)。我们知道每个喷头的位置(离草坪中心线左端的距离),以及它能覆盖到的浇灌范围。
请问:如果要同时浇灌整块草坪,最少需要打开多少个喷头?
【代码】
#include<bits/stdc++.h>
using namespace std;
struct node{ //结构体变量声明
double l,r;
}a[15005];
int cmp(node x,node y){
return x.l<y.l;
}
int main(){
int T;
cin>>T; //输入有几组数据
while(T--){
int n,cnt=0;
double l,w;
cin>>n>>l>>w; //运用T--循环,输入每组数据中有几个喷头,长和宽
for(int i=0;i<n;i++){
double p,r;
cin>>p>>r; //运用for循环输入喷头的位置,半径
if(r<w/2.0) //判断喷头覆盖半径是否小于草坪的宽度
continue;
double t=sqrt(r*r-(w/2.0)*(w/2.0)); //计算覆盖范围在草坪上的有效长度
a[cnt].l=p-t;
a[cnt++].r=p+t; //喷头的位置减去和加上有效长度,得到有效范围
}
sort(a,a+cnt,cmp);
int i=0,ans=0,f=0;
double rr=0,mx;
while(i<cnt){
if(rr<a[i].l){
f=1;
break;
}
if(rr>=l)
break;
mx=-1.0;
while(i<cnt&&rr>=a[i].l) //当rr大于一组数据的长度
mx=max(mx,a[i].r),i++;
rr=mx;
ans++;
}
if(f==1){
puts("-1");
continue;
}
cout<<ans<<endl; //输出ans
}
}
【感悟】
题目要求输出浇灌整个草坪需要开最少的喷头数,运用贪心,来求出最优的策略。结构体变量的声明和排序。通过毕达哥拉斯定理求出相应的范围。最后,计算出能否完成浇灌,能则输出最小的喷头数。