hdu 4033 Regular Polygon (几何题 二分答案)

 在正多边形内部有一点,给出该点到多边形各点的距离,求正多边形的边长

从正多边形的定义出发,各边相等各角也相等的多边形,直接二分答案 , 枚举边长 , 满足各边所对角的和为2*pi的即可能为答案 ,此时再判断一下多边型各角是否相等即可,出现impossible的情况有2种 , 一个是二分搜不到满足条件的边长 ,一个是搜到边不满足角相等,因为三角形2边确定,则夹角所对边和夹角都是单调递增。

#include <cstdio>
#include <cmath>

const double pi=acos(-1.0);
const double eps=1e-6;
const int maxn=105;
double dis[maxn];
int n;

double Acos(double a , double b , double c)
{
    return acos((a*a+b*b-c*c)/(2*a*b));
}

bool Isregular(double x)
{
    double tmp=Acos(x,dis[0],dis[n-1])+Acos(x,dis[0],dis[1]);
    for (int i=1 ; i<n ; ++i)
    {
        //printf("%lf  ==%lf  %lf\n",tmp , Acos(x,dis[i],dis[i-1]))
        if(fabs(tmp-Acos(x,dis[i],dis[i-1])-Acos(x,dis[i],dis[i+1]))>eps)return false;
    }
    return true;
}

int main ()
{
    int cas;
    scanf("%d",&cas);
    for (int I=1 ; I<=cas ; ++I)
    {
        scanf("%d",&n);
        for (int i=0 ; i<n ; ++i)
        {
            scanf("%lf",dis+i);
        }
        dis[n]=dis[0];
        bool flag=false;
        double ans;
        double low=0.0 ,high=20005.0;
        while (fabs(high-low)>eps)
        {
            double mid=(low+high)/2;
            double delta=0.0;
            for (int i=0 ; i<n ; ++i)
            {
                delta += Acos(dis[i] , dis[i+1] , mid);
            }

            if(fabs(delta-2*pi)<eps)
            {
                {
                    ans=mid;
                    flag=true;
                    break;
                }
            }
            if(delta<2*pi)low=mid;
            else high=mid;
        }
        if(flag && Isregular(ans))printf("Case %d: %0.3lf\n" , I , ans);
        else printf("Case %d: impossible\n",I);
    }
    return 0;
}


 

你可能感兴趣的:(hdu 4033 Regular Polygon (几何题 二分答案))