Regular Polygon
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Submission(s): 2905 Accepted Submission(s): 884
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
Recommend
本题给定正多边形内一点到各个顶点的距离,要求是否存在这样的多边形。
本题的突破口是多边形为正多边形,几个边相等,对应的内角相等。我们可以二分枚举边长,只要同时满足下面的两个条件即可:
1.构成三角形
2.角度等于360.
本题在卡精度,不知为什么一直WA。
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
const double PI2=2*acos(-1.0);
const double eps=1e-8;
const int MAXN=100+10;
double Edg[MAXN];
int n;
double Angle(double a,double b,double c)
{
return acos((a*a+b*b-c*c)/(2.0*a*b));
}
int IsPology(double len)
{
double sumangle=0.0;
for(int i=1;i<n+1;i++)
{
sumangle+=Angle(Edg[i],Edg[i-1],len);
}
if(fabs(sumangle-PI2)<=eps)
return 0;
else if(sumangle>PI2)
return -1;
return 1;
}
void Solve()
{
double high,low,mid;
Edg[n]=Edg[0];
high=Edg[0]+Edg[1];
low=fabs(Edg[0]-Edg[1]);
for(int i=2;i<n+1;i++)
{
double tmp=Edg[i]+Edg[i-1];
if(high<tmp)
high=tmp;
tmp=fabs(Edg[i]-Edg[i-1]);
if(tmp>low)
low=tmp;
}
bool flag=false;
high-=eps;
low+=eps;
while(high>low+eps)
{
mid=(high+low)/2.0;
int t=IsPology(mid);
if(t==0)
{
flag=true;
break;
}
else if(t==-1)
high=mid;
else low=mid;
}
if(flag)
printf("%0.3lf\n",mid);
else printf("impossible\n");
}
int main()
{
int cas;
int tag=1;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lf",&Edg[i]);
printf("Case %d: ",tag++);
Solve();
}
system("pause");
return 0;
}