牛客网暑期ACM多校训练营(第三场)J
#include <iostream>
#include <cstdio>
#include <cmath>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define PI acos(-1.0)
#define EPS 1e-7
using namespace std;
inline int DB(double x) {
if(x<-EPS) return -1;
if(x>EPS) return 1;
return 0;
}
struct point {
double x,y;
point() {}
point(double _x,double _y):x(_x),y(_y) {}
point operator-(point a) {
return point(x-a.x,y-a.y);
}
point operator+(point a) {
return point(x+a.x,y+a.y);
}
double operator*(point a) {
return x*a.y-y*a.x;
}
point oppose() {
return point(-x,-y);
}
double length() {
return sqrt(x*x+y*y);
}
point adjust(double L) {
L/=length();
return point(x*L,y*L);
}
point vertical() {
return point(-y,x);
}
double operator^(point a) {
return x*a.x+y*a.y;
}
};
struct segment {
point a,b;
segment() {}
segment(point _a,point _b):a(_a),b(_b) {}
point intersect(segment s) {
double s1=(s.a-a)*(s.b-a);
double s2=(s.b-b)*(s.a-b);
double t=s1+s2;
s1/=t;
s2/=t;
return point(a.x*s2+b.x*s1,a.y*s2+b.y*s1);
}
point vertical(point p) {
point t=(b-a).vertical();
return intersect(segment(p,p+t));
}
int isonsegment(point p) {
return DB(min(a.x,b.x)-p.x)<=0&&
DB(max(a.x,b.x)-p.x)>=0&&
DB(min(a.y,b.y)-p.y)<=0&&
DB(max(a.y,b.y)-p.y)>=0;
}
};
struct circle {
point p;
double R;
};
circle C;
point p[205];
int n;
double cross_area(point a,point b,circle C) {
point p=C.p;
double R=C.R;
int sgn=DB((b-p)*(a-p));
double La=(a-p).length(),Lb=(b-p).length();
int ra=DB(La-R),rb=DB(Lb-R);
double ang=acos(((b-p)^(a-p))/(La*Lb));
segment t(a,b);
point s;
point h,u,temp;
double ans,L,d,ang1;
if(!DB(La)||!DB(Lb)||!sgn) ans=0;
else if(ra<=0&&rb<=0) ans=fabs((b-p)*(a-p))/2;
else if(ra>=0&&rb>=0) {
h=t.vertical(p);
L=(h-p).length();
if(!t.isonsegment(h)||DB(L-R)>=0) ans=R*R*(ang/2);
else {
ans=R*R*(ang/2);
ang1=acos(L/R);
ans-=R*R*ang1;
ans+=R*sin(ang1)*L;
}
} else {
h=t.vertical(p);
L=(h-p).length();
s=b-a;
d=sqrt(R*R-L*L);
s=s.adjust(d);
if(t.isonsegment(h+s)) u=h+s;
else u=h+s.oppose();
if(ra==1) temp=a,a=b,b=temp;
ans=fabs((a-p)*(u-p))/2;
ang1=acos(((u-p)^(b-p))/((u-p).length()*(b-p).length()));
ans+=R*R*(ang1/2);
}
return ans*sgn;
}
double cal_cross(circle C,point p[],int n) {
double ans=0;
int i;
p[n]=p[0];
for(i=0; i<n; i++) ans+=cross_area(p[i],p[i+1],C);
return fabs(ans);
}
int main()
{
while(scanf("%d", &n)!=EOF){
for(int i=0;i<n;i++) scanf("%lf%lf", &p[i].x, &p[i].y);
double area1 = 0;
for(int i = 0; i < n; i++) {
int nx = (i + 1) % n;
area1 += p[i] * p[nx];
}
if(area1 < 0) area1 = -area1;
area1 /= 2;
int q; scanf("%d", &q);
while(q--) {
scanf("%lf%lf", &C.p.x, &C.p.y);
double a, b, tar;
scanf("%lf%lf", &a, &b);
double area2 = area1 * (1 - a / b);
// printf("%.3f\n", area2);
double l = 0, r = 3e4;
// printf("%.3f %.3f\n", o.x, o.y);
for(int i = 1; i <= 60; i++) {
double mid = (l + r) / 2;
C.R = mid;
double area = cal_cross(C, p, n);
if(area >= area2) r = mid;
else l = mid;
}
printf("%.12f\n", l);
}
}
return 0;
}
/********************
4
0 0
1 0
2 0
3 0
1
1 1 1 2
********************/