原题:http://acm.hdu.edu.cn/showproblem.php?pid=4033
Regular Polygon
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Submission(s): 3054 Accepted Submission(s): 925
Problem Description
In a 2_D plane, there is a point strictly in a regular polygon with N sides. If you are given the distances between it and N vertexes of the regular polygon, can you calculate the length of reguler polygon's side? The distance is defined as dist(A, B) = sqrt( (Ax-Bx)*(Ax-Bx) + (Ay-By)*(Ay-By) ). And the distances are given counterclockwise.
Input
First a integer T (T≤ 50), indicates the number of test cases. Every test case begins with a integer N (3 ≤ N ≤ 100), which is the number of regular polygon's sides. In the second line are N float numbers, indicate the distance between the point and N vertexes of the regular polygon. All the distances are between (0, 10000), not inclusive.
Output
For the ith case, output one line “Case k: ” at first. Then for every test case, if there is such a regular polygon exist, output the side's length rounded to three digits after the decimal point, otherwise output “impossible”.
Sample Input
2 3 3.0 4.0 5.0 3 1.0 2.0 3.0
Sample Output
Case 1: 6.766 Case 2: impossible
思路:直接二分要求的边长,然后计算该边长情况下的内角和是否约等于2*pi,当约等于时符合
AC代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
/*
author:YangSir
time:2014/5/17
*/
#define x 1e-8//精度稍微开大点
#define tp 2*acos(-1.0)//这是2π
double d[150],mid;
double min(double a,double b)
{
return a>b?b:a;
}
double ACOS(double a,double b,double c)
{
return acos((a*a+b*b-c*c)/(2.0*a*b));//余弦定理求cos,再求acos
}
double max(double a,double b)
{
return a>b?a:b;
}
int solve(int n)
{
int flag,i;
double r=20000,l=0,sum;
flag=0;
for(i=0;i<n;i++)
{
r=min(r,d[i]+d[i+1]);
l=max(l,fabs(d[i]-d[i+1]));
}
while(r-l>x)
{
mid=(r+l)/2;
sum=0;
for(i=0;i<n;i++)
sum+=ACOS(d[i],d[i+1],mid);//求该情况下的内角和
if(fabs(sum-tp)<x)//判断是否约等于
{
flag=1;
break;
}
if(sum>tp)
r=mid;
else
l=mid;
}
return flag;
}
int main()
{
int t,T,i,n;
scanf("%d",&T);
for(t=1;t<=T;t++)
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%lf",&d[i]);
d[n]=d[0];
printf("Case %d: ",t);
if(solve(n))
printf("%.3lf\n",mid);
else
printf("impossible\n");
}
return 0;
}