喷水装置
题目
长L米,宽W米的草坪里装有n个浇灌喷头。每个喷头都装在草坪中心线上(离两边各W/2米)。我们知道每个喷头的位置(离草坪中心线左端的距离),以及它能覆盖到的浇灌范围。
请问:如果要同时浇灌整块草坪,最少需要打开多少个喷头?
输入格式
输入包含若干组测试数据。
第一行一个整数T表示数据组数。
每组数据的第一行是整数n、L和W的值,其中n≤10 000。
接下来的n行,每行包含两个整数,给出一个喷头的位置和浇灌半径。
如图1所示的示意图是样例输入的第一组数据所描述的情况。
输出格式
对每组测试数据输出一个数字,表示要浇灌整块草坪所需喷头数目的最小值。如果所有喷头都打开还不能浇灌整块草坪,则输出-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。
程序代码
#include<bits/stdc++.h>
#include<algorithm>
using namespace std;
#define MAXN 10000
int n;//喷头个数
double L,W;//草坪长度和宽度
int cnt;
struct nozzle{
double location;
double radius;
double front_location;
double behind_location;
}nozzles[MAXN];
bool cmp(nozzle a,nozzle b){
return a.front_location<b.front_location;
}
void input(){
scanf("%d %lf %lf",&n,&L,&W);
int i = 0;
for(i;i < n;i++){
scanf("%lf %lf",&nozzles[i].location,&nozzles[i].radius);
if(nozzles[i].radius <= W/2)
continue;
cnt++;
nozzles[i].front_location = nozzles[i].location - sqrt(nozzles[i].radius*nozzles[i].radius - W*W/4.0);
nozzles[i].behind_location = nozzles[i].location + sqrt(nozzles[i].radius*nozzles[i].radius - W*W/4.0);
}
sort(nozzles,nozzles + cnt,cmp);
}
void caculate(){
int min = 0,i=0;
double sum = 0;
bool flag = true;
while(sum < L){
min ++;
double temp = sum;
for(i = 0;nozzles[i].front_location <= temp && i <= cnt;i++){
if(sum < nozzles[i].behind_location){
sum = nozzles[i].behind_location;
}
}
if(temp == sum && temp < L){
cout<<"-1"<<endl;
flag = false;
break;
}
}
if(flag)
cout<<min<<endl;
}
int main(){
int count = 0;
cin>>count;
while(count > 0){
input();
caculate();
count--;
}
}