您的位置:首页 > 其它

Watering Grass

2015-08-08 15:09 274 查看
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/E

题意:

有n个喷头安装在长l米宽w米长的水平草条中间的水平线上,给出每个喷头的半径。为了让水平草条都浇到水,最少需要多少喷头?如果没办法完全浇到水平草条。输出-1。

案例:

input

3 10 1

3 5

9 3

6 1

3 10 1

5 3

1 1

9 1

output

2

-1

思路分析:

当喷头的射程半径小于等于水平草条的宽度的一半,不能完全覆盖草坪,可以直接忽视这样的点,而另外的可以通过加减sqrt(r*r-w*w)得出喷头范围的左右端点,就成了一个区间覆盖问题,与MINIMAL COVERAGE的思路是一样的。不懂的人可以参考那题。

源代码如下:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
double a[2][10010],b[10010];
int n,count,j;
double l,w;
void search(double le)    //区间覆盖
{
for(int i=0;i<j;i++)
if(a[0][i]<=le&&a[1][i]>le&&a[1][i]>b[count])
b[count]=a[1][i];
if(b[count]!=0&&b[count]<l)
{
count++;
search(b[count-1]);
}
}
int main()
{
while(scanf("%d%lf%lf",&n,&l,&w)!=EOF)
{
double o,r,nr;            //必须用double
j=0;
count=0;
memset(b,0,sizeof(b));
for(int i=0;i<n;i++)
{
scanf("%lf%lf",&o,&r);
if(r<=w/2.0) continue;                     //不需考虑的情况
nr=sqrt(r*r-w*w/4.0);                     //预处理
a[0][j]=o-nr;
a[1][j]=o+nr;
j++;
}
search(0);
if(b[count]<l)
printf("-1\n");
else
printf("%d\n",count+1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: