题目链接:NYOJ 12 喷水装置(二)
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
struct node{ //定义结构体,存储每个喷水装置可以全部覆盖的起点和终点
double st,en;
}a[10001];
int cmp(node m, node n) //结构体排序
{
if(m.st<n.st) // 按起点升序
return true;
else if(m.st==n.st && m.en>n.en) //若起点相同,按终点降序排序
return true;
return false;
}
int main()
{
int N;
scanf("%d",&N);//测试数据组数
while(N--)
{
double w,h,xi,ri,b;
int s=0,r=1,i,n;
scanf("%d %lf %lf",&n,&w,&h); //n为喷水装置个数 ,w为横向长度,h为纵向长度
for(i=0;i<n;i++)
{
scanf("%lf %lf",&xi,&ri);//xi为喷水装置的横坐标,ri为装置的喷水半径
b=ri*ri-h*h/4;
if(b>0) //ri> h/2
b=sqrt(b);
else b=0.0; //ri< h/2 如果喷水半径<=纵向长度,那么此装置不起作用
a[i].st=xi-b; //起点
a[i].en=xi+b; //终点
}
sort(a,a+n,cmp);
int max,end=0; //end为每增加一个喷水装置,所能达到的最大横向长度
while(end<w)
{
max=0; //max为每增加一个装置所能够增加的 最大横向覆盖长度
for(i=0;i<n && a[i].st<=end;i++)
if((a[i].en-end)>max)
max=a[i].en-end;
if(max==0) //如果end<w,但是没有符合条件的max,结束循环
{
r=0;
break;
}
else
{
end+=max;
s++;
}
}
if(r)
printf("%d\n",s);
else //未能覆盖完
printf("0\n");
}
return 0;
}