版权声明:转载请注明出处 https://blog.csdn.net/FSAHFGSADHSAKNDAS/article/details/82115928
链接
http://codeforces.com/gym/101623/attachments
题解
我已经不记得自己上次写几何题是什么时候了
这题思路很简单,就是二分一下多边形外接圆的半径(即原点到一个顶点的距离),然后求出内外两个多边形,作个比就完事了
涨姿势
这题的比值化简之后是 ,因为两个数都是正数,所以我们其实可以在比较的过程中先暂且用 作比,最后输出的时候再平方,减小精度误差
代码
#include <bits/stdc++.h>
#define maxn 1010
#define eps 1e-8
using namespace std;
const double pi=acos(-1);
struct point
{
double x, y;
point(){}
point(double xx, double yy){x=xx,y=yy;}
}p[10], pt[maxn];
struct vec
{
point pt;
double x, y;
vec(){}
vec(point p1, point p2){pt=p1, x=p2.x-p1.x, y=p2.y-p1.y;}
vec(double xx, double yy){x=xx,y=yy;}
}v[10];
int N;
double operator*(vec v1, vec v2){return v1.x*v2.y-v2.x*v1.y;}
void init()
{
int i;
scanf("%d",&N);
for(i=1;i<=N;i++)scanf("%lf%lf",&pt[i].x,&pt[i].y);
}
int cnt(int k, double r)
{
int i, j, c=0;
for(i=1;i<=k;i++)p[i]=point(r*cos((i-1)*2*pi/k),r*sin((i-1)*2*pi/k));
for(i=1;i<k;i++)v[i]=vec(p[i],p[i+1]);
v[k]=vec(p[k],p[1]);
for(i=1;i<=N;i++)
{
for(j=1;j<=k;j++)
{
if(vec(pt[i].x-v[j].pt.x,pt[i].y-v[j].pt.y)*v[j]>eps)break;
}
if(j>k)c++;
}
return c;
}
void work()
{
int k, i, ANS;
double S1, S2, ans=-1, l, r, mid, r1, r2;
for(k=3;k<=8;k++)
{
l=eps, r=1e9;
for(i=1;i<=1000;i++)
{
mid=(l+r)/2.0;
if(cnt(k,mid)==N)r=mid;
else l=mid;
}
r1=l;
l=eps, r=1e9;
for(i=1;i<=1000;i++)
{
mid=(l+r)/2.0;
if(cnt(k,mid)!=0)r=mid;
else l=mid;
}
r2=l;
if(r2/r1>ans+eps)ans=r2/r1, ANS=k;
}
printf("%d %.10lf\n",ANS,ans*ans);
}
int main()
{
init();
work();
return 0;
}