HDOJ/HDU 4033 2011成都网络赛C题

本文介绍了一种计算平面中正多边形边长的方法,通过给定点到各顶点的距离,利用二分查找结合余弦定理计算边长,并提供了一个C++实现示例。

Regular Polygon

Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 1041Accepted 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; }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值