Watering Grass(贪心) link.
翻译
n洒水器安装在水平的草条上,草条长l米,宽w米。每个喷水器安装在条带的水平中心线上。
对于每个喷水装置,我们都将定位距中心线左端的距离及其工作半径。
为了给整片草地浇水,最少要打开多少个洒水器?
输入
输入由多个事例组成。每种情况的第一行包含整数n、l和wn≤10000。
接下来的n行包含两个整数,给出喷水器的位置及其半径。
操作。(上图说明了样本输入的第一个案例。)
输出
对于每个测试用例,输出灌溉整个草条所需的最小洒水器数量。
如果不可能对整个条带输出“-1”进行浇水。
解析
需要注意的是,当洒水器的直径要小于等于草坪宽度时,这个洒水器相当于无效。然后根据区间左边界进行从小到大的排序。排序完成后,通过判定一个区间左界限是否小于等于前一个区间的右界限来确定需要的喷洒装置的数量。还有以下几种特殊情况:
当排完序后发现,洒水器的最左端或最右端的有效区间,不能覆盖草坪的最左端最右端,则输出-1。
或排序完成后中间出现断层,输出-1。
或排序完后出现大圈套小圈,则明显选择大圈。
代码
#include<queue>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n;
double l,w;
struct node
{
double m;
double n;
}q[10010];
bool cmp(node u,node v)
{
return u.m<v.m;
}
int main()
{
while(~scanf("%d%lf%lf",&n,&l,&w))
{
int k=0,flag=0,ans=0,i=0;
double a,b,x=0,y=0;
for(int i=0;i<n;i++)
{
scanf("%lf%lf",&a,&b);
if(b*2<=w)
continue;
double li=sqrt(b*b-(w/2.0)*(w/2.0));
q[k].m=a-li;
q[k++].n=a+li;
}
sort(q,q+k,cmp);
if(q[0].m>0||k==0)
{
printf("-1\n");
continue;
}
while(i<n)
{
int j=i;
while(q[i].m<=x&&i<n)
{
if(y<q[i].n)
{
y=q[i].n;
}
i++;
}
if(j==i)
break;
x=y;
ans++;
if(y>=l)
break;
}
if(y>=l)
printf("%d\n",ans);
else
printf("-1\n");
}
return 0;
}