HDU 4033 Regular Polygon【二分】

题意: 知道了正多边形内部一个点和其他所有点的距离,假如此正多边形存在则输出此正多边形边长,否则输出 impossible。

分析:二分多边形的边长,对于每一个边长求出对应的内角和,假如内角和小与 360,则此边长比实际值要小,否则大于实际边长。

#include<stdio.h>
#include<string.h>
#include<math.h>
const double eps=1e-6;
const double P=acos(-1.0);
double d[105];
double ab(double a)
{ return a>0?a:-a; }
int n;
double angle(double  x)
{
    double ang;
    double ans=0;
    int i;
    for(i=0;i<n;i++)
    {
        if(x>d[i]+d[(i+1)%n]-eps)
            return -1;
        if(x<ab(d[i]-d[(i+1)%n]))
            return -2;
        ang=(d[i]*d[i]+d[(i+1)%n]*d[(i+1)%n]-x*x)/(2.0*d[i]*d[(i+1)%n]);
          ang=acos(ang);
        ans+=ang;
    }
    return ans;
}
int main()
{
    int t,i,ca=1;
    double l,r,mid,tmp,res;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        l=0;
        r=20000;
        for(i=0;i<n;i++)
            scanf("%lf",&d[i]);
        res=-1;
        int tim=0;
        int flag=0;
        while(l<r+eps)
        {
            if(ab(r-l)<eps)
            {
                tim++;
                if(tim>=2)
                    break;
            }
            mid=(l+r)/2;
            tmp=angle(mid);
            if(ab(tmp-2*P)<eps)
            {
                flag=1;
                break;
            }
            if(tmp==-1||tmp>2*P+eps)
                r=mid;
            else l=mid;
        }
        printf("Case %d: ",ca++);
        if(flag)
            printf("%.3lf\n",mid);
        else printf("impossible\n");
    }
    return 0;
}

 

posted @ 2012-09-08 10:29  'wind  阅读(162)  评论(0编辑  收藏  举报