Regular Polygon
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Submission(s): 1041 Accepted Submission(s): 295
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
Source
可以直接二分那个边长,然后通过计算内角和是否大于360来判断当前的边长是否合理
我的代码:
#include<stdio.h>
#include<math.h>
#include<algorithm>
#define PI acos(-1.0)
#define eps 1e-8
using namespace std;
double a[105];
int n;
double cal(double x)
{
int i;
double sita=0,tmp1,tmp2;
for(i=1;i<=n;i++)
{
tmp1=a[i]*a[i]+a[i+1]*a[i+1]-x*x;
tmp2=2*a[i]*a[i+1];
sita=sita+acos(tmp1/tmp2);
}
return sita;
}
double solve(double left,double right)
{
int k;
double mid;
for(k=1;k<=200;k++)
{
mid=(left+right)/2;
if(cal(mid)>2*PI+eps)
{
right=mid;
}
else
{
left=mid;
}
}
return left;
}
double max(double a,double b)
{
if(a>b)
return a;
else
return b;
}
double min(double a,double b)
{
if(a>b)
return b;
else
return a;
}
int main()
{
int i,t,T;
double ans,left,right;
scanf("%d",&T);
for(t=1;t<=T;t++)
{
left=0,right=99999;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%lf",&a[i]);
a[n+1]=a[1];
for(i=1;i<=n;i++)
{
right=min(right,a[i]+a[i+1]);
left=max(left,fabs(a[i]-a[i+1]));
}
right=right-eps;
if(left>right)
{
printf("Case %d: impossible\n",t);
continue;
}
ans=solve(left,right);
if(fabs(cal(ans)-2*PI)<eps)
printf("Case %d: %.3lf\n",t,ans);
else
printf("Case %d: impossible\n",t);
}
return 0;
}