Harry Potter and J.K.Rowling
In July 31st, last month, the author of the famous novel series J.K.Rowling celebrated her 46th birthday. Many friends gave their best wishes. They gathered together and shared one large beautiful cake.
Rowling had lots of friends, and she had a knife to cut the cake into many pieces. On the cake there was a cherry. After several cuts, the piece with the cherry was left for Rowling. Before she enjoyed it, she wondered how large this piece was, i.e., she wondered how much percentage of the cake the piece with the only cherry has.
\(n\leq 2000\)
题解
半平面交+凸多边形与圆的面积交。
然后被精度卡烂了。
时间复杂度\(O(n\log n)\)。
struct point {double x,y;};
IN point operator+(CO point&a,CO point&b){
return (point){a.x+b.x,a.y+b.y};
}
IN point operator-(CO point&a,CO point&b){
return (point){a.x-b.x,a.y-b.y};
}
IN point operator*(CO point&a,double b){
return (point){a.x*b,a.y*b};
}
IN point operator/(CO point&a,double b){
return (point){a.x/b,a.y/b};
}
IN double dot(CO point&a,CO point&b){
return a.x*b.x+a.y*b.y;
}
IN double cross(CO point&a,CO point&b){
return a.x*b.y-a.y*b.x;
}
IN double len(CO point&a){
return sqrt(dot(a,a));
}
IN double angle(CO point&a,CO point&b){
double w=dot(a,b)/len(a)/len(b);
w=max(w,-1.0),w=min(w,1.0); // edit 3
return acos(w);
}
struct line {point x,y;};
IN bool on_left(CO point&a,CO line&b){
return cross(a-b.x,b.y)<0;
}
IN int quad(CO point&a){
if(a.x>0 and a.y>=0) return 1;
else if(a.x<=0 and a.y>0) return 2;
else if(a.x<0 and a.y<=0) return 3;
else return 4;
}
IN bool operator<(CO line&a,CO line&b){
if(quad(a.y)!=quad(b.y)) return quad(a.y)0; // edit 2
}
IN point intersect(CO line&a,CO line&b){
return b.x+b.y*cross(b.x-a.x,a.y)/cross(a.y,b.y);
}
CO double pi=acos(-1),eps=1e-6;
vector seg_cross_circle(CO point&a,CO point&b,double r){
double dx=b.x-a.x,dy=b.y-a.y;
double A=dx*dx+dy*dy;
double B=2*dx*a.x+2*dy*a.y; // edit 1
double C=a.x*a.x+a.y*a.y-r*r;
double delta=B*B-4*A*C;
vector ans;
if(delta<-eps) return ans; // edit 2
delta=sqrt(max(delta,0.0));
double t1=(-B+delta)/(2*A);
double t2=(-B-delta)/(2*A);
if(-t10?1:-1),ans=0;
if(AinC and BinC) ans=abs(cross(a,b)); // edit 4
else if(AinC or BinC){
if(BinC) swap(a,b);
vector tmp=seg_cross_circle(a,b,r);
ans=abs(cross(a,tmp[0]))+r*r*angle(tmp[0],b);
}
else{
vector p=seg_cross_circle(a,b,r);
ans=r*r*angle(a,b);
if(p.size()==2){
ans-=r*r*angle(p[0],p[1]);
ans+=abs(cross(p[0],p[1]));
}
}
// cerr<<"ans="<();
ln[1].x=(point){0,-r},ln[1].y=(point){1,0};
ln[2].x=(point){r,0},ln[2].y=(point){0,1};
ln[3].x=(point){0,r},ln[3].y=(point){-1,0};
ln[4].x=(point){-r,0},ln[4].y=(point){0,-1};
for(int i=5;i<=n;++i){
point a,b;scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
ln[i].x=a,ln[i].y=b-a;
}
point o;scanf("%lf%lf",&o.x,&o.y);
for(int i=5;i<=n;++i)
if(!on_left(o,ln[i])) ln[i].y=ln[i].y*-1;
n=halfplane(n),p[n+1]=p[1];
// cerr<<"p=";
// for(int i=1;i<=n+1;++i)
// cerr<<" ("<();
for(int i=1;i<=T;++i){
printf("Case %d: ",i);
real_main();
}
return 0;
}