题目:给你一个多变形,再给你几个圆心点,问每个圆心点的半径为多少时,圆的面积为多边形面积的(1-p/q);
思路:二分,注意精度,拼凑模板
#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxp = 1010;
int sgn(double x){
if(fabs(x) < eps)return 0;
if(x < 0)return-1;
else return 1;
}
inline double sqr(double x){return x*x;}
struct Point{
double x,y;
Point(){}
Point(double _x,double _y){
x = _x;
y = _y;
}
bool operator == (Point b)const{
return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;
}
bool operator < (Point b)const{
return sgn(x-b.x)== 0-sgn(y-b.y)?0:x<b.x;
}
Point operator-(const Point &b)const{
return Point(x-b.x,y-b.y);
}
double operator ^(const Point &b)const{
return x*b.y-y*b.x;
}
double operator *(const Point &b)const{
return x*b.x + y*b.y;
}
double len(){
return hypot(x,y);
}
double len2(){
return x*x + y*y;
}
double distance(Point p){
return hypot(x-p.x,y-p.y);
}
Point operator +(const Point &b)const{
return Point(x+b.x,y+b.y);
}
Point operator *(const double &k)const{
return Point(x*k,y*k);
}
Point operator /(const double &k)const{
return Point(x/k,y/k);
}
double rad(Point a,Point b){
Point p = *this;
return fabs(atan2( fabs((a-p)^(b-p)),(a-p)*(b-p) ));
}
Point trunc(double r){
double l = len();
if(!sgn(l))return *this;
r /= l;
return Point(x*r,y*r);
}
};
struct Line{
Point s,e;
Line(){}
Line(Point _s,Point _e){
s = _s;
e = _e;
}
double length(){
return s.distance(e);
}
double dispointtoline(Point p){
return fabs((p-s)^(e-s))/length();
}
Point lineprog(Point p){
return s + ( ((e-s)*((e-s)*(p-s)))/((e-s).len2()) );
}
Point symmetrypoint(Point p){
Point q = lineprog(p);
return Point(2*q.x-p.x,2*q.y-p.y);
}
};
struct circle{
Point p;
double r;
circle(){}
bool operator == (circle v){
return (p==v.p) && sgn(r-v.r)==0;
}
bool operator < (circle v)const{
return ((p<v.p)||((p==v.p)&&sgn(r-v.r)<0));
}
int relation(Point b){
double dst = b.distance(p);
if(sgn(dst-r) < 0)return 2;
else if(sgn(dst-r)==0)return 1;
return 0;
}
int relationline(Line v){
double dst = v.dispointtoline(p);
if(sgn(dst-r) < 0)return 2;
else if(sgn(dst-r) == 0)return 1;
return 0;
}
int pointcrossline(Line v,Point &p1,Point &p2){
if(!(*this).relationline(v))return 0;
Point a = v.lineprog(p);
double d = v.dispointtoline(p);
d = sqrt(r*r-d*d);
if(sgn(d) == 0){
p1 = a;
p2 = a;
return 1;
}
p1 = a + (v.e-v.s).trunc(d);
p2 = a-(v.e-v.s).trunc(d);
return 2;
}
double areatriangle(Point a,Point b){
if(sgn((p-a)^(p-b)) == 0)return 0.0;
Point q[5];
int len = 0;
q[len++] = a;
Line l(a,b);
Point p1,p2;
if(pointcrossline(l,q[1],q[2])==2){
if(sgn((a-q[1])*(b-q[1]))<0)q[len++] = q[1];
if(sgn((a-q[2])*(b-q[2]))<0)q[len++] = q[2];
}
q[len++] = b;
if(len == 4 && sgn((q[0]-q[1])*(q[2]-q[1]))>0)swap(q[1],q
[2]);
double res = 0;
for(int i = 0;i < len-1;i++){
if(relation(q[i])==0||relation(q[i+1])==0){
double arg = p.rad(q[i],q[i+1]);
res += r*r*arg/2.0;
}
else{
res += fabs((q[i]-p)^(q[i+1]-p))/2.0;
}
}
return res;
}
};
struct polygon{
int n;
Point p[maxp];
Line l[maxp];
void add(Point q){
p[n++] = q;
}
double getarea(){
double sum = 0;
for(int i = 0;i < n;i++){
sum += (p[i]^p[(i+1)%n]);
}
return fabs(sum)/2;
}
double areacircle(circle c){
double ans = 0;
for(int i = 0;i < n;i++){
int j = (i+1)%n;
if(sgn( (p[j]-c.p)^(p[i]-c.p) ) >= 0)
ans += c.areatriangle(p[i],p[j]);
else ans-= c.areatriangle(p[i],p[j]);
}
return fabs(ans);
}
};
polygon a;
circle c;
double P,Q;
#define Eps 1e-6
bool check(double r)
{
c.r=r;
double tmp1=a.areacircle(c);
double tmp2=a.getarea();
tmp1=tmp2-tmp1;
if(tmp1*Q+Eps<=tmp2*P)
return true;
return false;
}
int main()
{
scanf("%d",&a.n);
for(int i=0;i<a.n;i++)
scanf("%lf%lf",&a.p[i].x,&a.p[i].y);
int t=0;
scanf("%d",&t);
while(t--)
{
scanf("%lf%lf",&c.p.x,&c.p.y);
scanf("%lf%lf",&P,&Q);
double l=0.0,r=1e6;
while(r-l>Eps)
{
double mid=(l+r)/2.0;
if(check(mid))
r=mid;
else
l=mid;
}
printf("%.10lf\n",l);
}
return 0;
}