NWERC 2017 G.Glyph Recognition

版权声明:转载请注明出处 https://blog.csdn.net/FSAHFGSADHSAKNDAS/article/details/82115928

链接

http://codeforces.com/gym/101623/attachments

题解

我已经不记得自己上次写几何题是什么时候了
这题思路很简单,就是二分一下多边形外接圆的半径(即原点到一个顶点的距离),然后求出内外两个多边形,作个比就完事了

涨姿势

这题的比值化简之后是 r 1 2 r 2 2 ,因为两个数都是正数,所以我们其实可以在比较的过程中先暂且用 r 1 r 2 作比,最后输出的时候再平方,减小精度误差

代码

#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;
}

猜你喜欢

转载自blog.csdn.net/FSAHFGSADHSAKNDAS/article/details/82115928