实际上就是区间覆盖的变形,显然圆形能覆盖的矩形区域为圆形与总区域相交的长度,这就将圆形全部转换成了线段,这样就可以按区间覆盖来做了。
但是这个题比较恶心的地方是卡了比较严格的精度,这里需要额外注意一下。
代码如下:
#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; }