通过观察可以发现,为了使得选出的两个圆完全覆盖草地,前面的圆的与草地的交点小于后面圆与草地的交点。 所以我们可以简单的计算出圆与草地的交点,然后按照左交点排序,扫一遍即可。 我们在遍历的时候用两个变量维护当前已经选择的圆的右边和即将选得圆的左边,这是为了选出覆盖面积最大的符合要求的圆。
另外值得一提的是,UVA上的Debug上的答案是错误的。。。
细节参见代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 1000000000;
const double eps = 1e-6;
const int maxn = 10000+5;
double l,w;
int n;
struct node{
double v,rr,l,r;
bool operator < (const node& rhs) const {
return l < rhs.l;
}
}a[maxn],b;
int main() {
while(~scanf("%d%lf%lf",&n,&l,&w)) {
int cnt = 0;
for(int i=0;i<n;i++) {
scanf("%lf%lf",&b.v,&b.rr);
if(b.rr < w/2 || fabs(b.rr-w/2) < eps) continue;
double u = sqrt(b.rr*b.rr - w/2.0*w/2.0);
a[cnt].rr = b.rr; a[cnt].v = b.v;
a[cnt].l = b.v - u; a[cnt++].r = b.v + u;
}
sort(a,a+cnt);
int ans = 0;
double cur_l = 0, cur_r = 0;
for(int i=0;i<cnt;i++) {
if(cur_l > a[i].l || fabs(cur_l-a[i].l) < eps)
cur_r = max(cur_r,a[i].r);
else {
if(fabs(cur_l - cur_r)>eps) {
cur_l = cur_r;
ans++; i--;
}
}
if(i == cnt-1 && (cur_l > a[i].l || fabs(cur_l-a[i].l) < eps)) {
cur_l = cur_r ; ans++;
}
}
if(cur_l > l || fabs(cur_l - l) < eps) printf("%d\n",ans);
else printf("-1\n");
}
return 0;
}