二分两个多边形大小。附上一堆板子
#include<bits/stdc++.h>
#define mp make_pair
#define fir first
#define sec second
using namespace std;
typedef long long ll;
const double eps = 1e-12;
const double PI = acos(-1.0);
const int MX = 1e5+7;
struct Point {
double x, y;
void read(){
scanf("%lf%lf",&x,&y);
}
void print(){
printf("%.10f %.10f\n",x,y);
}
Point() {}
Point(double x,double y):x(x),y(y) {}
}q[MX];
typedef Point Vector;
int dcmp(double x) { //返回x的正负
if(fabs(x)<eps)return 0;
return x<0?-1:1;
}
Vector operator-(Vector A,Vector B) {return Vector(A.x - B.x, A.y - B.y);}
Vector operator+(Vector A,Vector B) {return Vector(A.x + B.x, A.y + B.y);}
Vector operator*(Vector A,double p) {return Vector(A.x*p, A.y*p);}
Vector operator/(Vector A,double p) {return Vector(A.x/p, A.y/p);}
bool operator<(const Point&a,const Point&b) {return a.x<b.x||(a.x==b.x&&a.y<b.y);}
bool operator==(const Point&a,const Point&b) {return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;}
double Dot(Vector A,Vector B) { //点积
return A.x*B.x+A.y*B.y;//如果改成整形记得加LL
}
double Cross(Vector A,Vector B) { //叉积
return A.x*B.y-A.y*B.x;//如果改成整形记得加LL
}
//向量长度
double Length(Vector A) {
return sqrt(Dot(A,A));
}
//2个向量之间的夹角
double Angle(Vector A,Vector B) {
return acos(Dot(A,B)/Length(A)/Length(B));
}
//向量的极角
double angle(Vector v) {
return atan2(v.y,v.x);
}
//计算ABC的有向面积
double Area(Point A,Point B,Point C) {
return Cross(B-A,C-A)/2;
}
//将A向量逆时针旋转rad
Vector Rotate( Vector A,double rad) {
return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
bool OnSegment(Point p,Point a1,Point a2) {
return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0;
}
int IsPointInPolygon(Point p, Point *R,int n){
int wn = 0;
for(int i = 0; i < n; i++){
const Point& p1 = R[i];
const Point& p2 = R[(i+1)%n];
if(p1 == p || p2 == p || OnSegment(p, p1, p2)) return -1; // 在边界上
int k = dcmp(Cross(p2-p1, p-p1));
if(k > 0) wn++;
if(k < 0) wn--;
}
if (wn == n) return 1; // 内部
return 0; // 外部
}
double PolygonArea(Point *p,int n) {
double area=0;
p[n] = p[0];
for(int i=1; i<n-1; i++)
area+=Cross(p[i]-p[0],p[i+1]-p[0]);
return fabs(area/2);
}
int ansx = 3;
double ans;
void get_p(Point *p, double r, int sz)
{
Vector v = Vector(r,0);
for(int i = 0; i < sz; i++){
p[i] = Rotate(v,PI*2*(i+1)/sz);
}
}
bool check1(Point *p, double r, int sz, int n)
{
get_p(p,r,sz);
for(int i = 0; i < n; i++){
int tmp = IsPointInPolygon(q[i],p,sz);
if(tmp == 0) return 0;
}
return 1;
}
bool check2(Point *p, double r, int sz, int n)
{
get_p(p,r,sz);
for(int i = 0; i < n; i++){
int tmp = IsPointInPolygon(q[i],p,sz);
if(tmp == 1) return 0;
}
return 1;
}
void work(int x, int n)
{
double rout = 0, rin = 0;;
double l = 0, r = 4000000;
Point p1[11],p2[11];
int cnt = 200;
while(cnt--){
double mid = (l+r)/2;
if(check1(p1,mid,x,n)) r = mid;
else l = mid;
}
rout = l;
l = 0, r = 4000000;
cnt = 200;
while(cnt--){
double mid = (l+r)/2;
if(check2(p2,mid,x,n)) l = mid;
else r = mid;
}
rin = l;
double t = PolygonArea(p2,x)/ PolygonArea(p1,x);
if(t > ans){
ans = t;
ansx = x;
}
}
int main()
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif // LOCAL
int n;
scanf("%d",&n);
for(int i = 0; i < n; i++)
q[i].read();
for(int i = 3; i <= 8; i++)
work(i,n);
printf("%d %.8f\n",ansx,ans);
return 0;
}