实际上就是区间覆盖的变形,显然圆形能覆盖的矩形区域为圆形与总区域相交的长度,这就将圆形全部转换成了线段,这样就可以按区间覆盖来做了。
但是这个题比较恶心的地方是卡了比较严格的精度,这里需要额外注意一下。
代码如下:
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct point
{
double x, y;
} pot[10002];
int cmp(const void *a, const void *b)
{
point *aa = (point *)a;
point *bb = (point *)b;
return aa->x > bb->x ? 1 : -1;
}
const double eps = 1e-9;
int main()
{
#ifdef test
freopen("in.txt", "r", stdin);
#endif
int n, i, l, w, r;
while(scanf("%d%d%d", &n, &l, &w) != EOF)
{
int ct = 0;
for(i = 0; i < n; i++)
{
double pos;
scanf("%lf%d", &pos, &r);
if(r * 2 <= w) // 圆形与矩形区域不相交,则直接舍去
continue;
double _dis = sqrt((double)r * r -(double)w * w / 4.0);
pot[ct].x = pos - _dis;
pot[ct].y = pos + _dis;
++ct;
}
qsort(pot, ct, sizeof(pot[0]), cmp);
int flag = 0, numct = 0, j = 0;
double begin = 0, end = 0;
for(int i = 0; i < ct; i++)
if(pot[i].x > end)
break;
else if(pot[i].y > end)
{
for(j = i; j < ct && pot[j].x - begin < eps; j++)
{
if(end - pot[j].y < -eps)
end = pot[j].y;
}
++numct;
if(end >= l)
{
flag = 1;
break;
}
begin = end;
}
if(flag)
printf("%d\n", numct);
else
printf("-1\n");
}
return 0;
}