http://acm.nyist.net/JudgeOnline/problem.php?pid=12&rec=sim
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define M 10010
struct zb
{
double a,b;
}c[M];
int cmp(zb p,zb q) //按左端点升序排列
{
return p.a<q.a;
}
int main()
{
int N,n,w,h,i,j,k;
int x,r;
int t,lap;
double a_max,b_max,tem;
cin>>N;
while(N--)
{
t=0;
lap=0;
cin>>n>>w>>h;
for(i=0,j=-1;i<n;i++)
{
cin>>x>>r;
if(2*r>h)
{
++j;
c[j].a=x-sqrt(pow(r,2)-pow(h/2,2));
c[j].b=x+sqrt(pow(r,2)-pow(h/2,2));
}
}
j++; //0到j,j+1个数
sort(c,c+j,cmp);
b_max=0;
for(i=0;i<j;i++)
{
if(c[i].a<=b_max) //如果第一个不小于0,那么接下来的都不小于0 ,不过按此判断太费时间
{
tem=c[i].b; //while第一步先从所有左端点<=0的线段中找出右端点最大的那个!!!
while(c[i].a<=b_max) //从所有符合要求的线段中找出右端点最大的那个
{
tem=c[i].b>tem?c[i].b:tem;
i++;
if(i==n)
break;
}
b_max=tem;
t++; //每找一条加一次
i--; //for循环中还要加一次,所以先减1
}
if(b_max>=w)
break;
}
if(b_max>=w)
cout<<t<<endl;
else
cout<<"0"<<endl;
}
return 0;
}