HDU 4033
Regular Polygon
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 2515 Accepted Submission(s): 782
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
1 //给定一个正num边型内一点距离所有点的距离,求边长。如果无解输出impossible 2 //所有角度和是否为2*PI,大于则缩小边,否则扩大边 3 #include <cstdio> 4 #include <iostream> 5 #include <cstring> 6 #include <cmath> 7 using namespace std; 8 9 double ch[200]; 10 const double PI = 4 * atan( double( 1 ) ); 11 //const double PI = 3.1415926;//这个wa 12 int num; 13 14 double is_triangle( double a, double b, double c ) 15 { 16 if( c > a + b ) 17 return 100; 18 else if( c < fabs( a - b ) ) 19 return -100; 20 else 21 return acos( ( a * a + b * b - c * c ) / ( 2 * a * b ) ); 22 } 23 24 double Acos( double a, double b, double c ) 25 { 26 return is_triangle( a, b, c ); 27 } 28 29 double total_angle( double mid ) 30 { 31 double ans = 0; 32 for( int i = 2; i <= num; ++i ) 33 { 34 double t = Acos( ch[i], ch[i-1], mid ); 35 if( fabs( t ) == 100 ) // 如果mid的这个取值使得某些相邻的两条边不 36 return t; // 能够形成三角形,则及时退出 37 else 38 ans += Acos( ch[i], ch[i-1], mid ); 39 } 40 return ans; 41 // 最后返回总的角度大小 42 } 43 44 double Bsearch( double ss, double ee ) 45 { 46 double left = ss, right = ee, mid, sum_angle; 47 while( right - left >= 1e-9 ) 48 { 49 mid = ( left + right ) / 2.0; 50 double t = total_angle( mid ); // 计算出一部分的角度总和 51 if( fabs( t ) == 100 ) 52 { 53 if( t > 0 ) 54 right = mid;//缩小边 55 else 56 left = mid;//扩大边 57 } 58 else 59 { 60 sum_angle = t + Acos( ch[1] , ch[num], mid ); 61 if( sum_angle - 2 * PI > 1e-9 ) 62 right = mid; 63 else if( sum_angle - 2 * PI < -1e-9 ) 64 left = mid; 65 else 66 return mid; 67 } 68 } 69 return 0; 70 } 71 72 int main( ) 73 { 74 int i,j,k,T; 75 cin>>T; 76 for(i = 1; i <= T; ++i ) 77 { 78 cin>>num; 79 for(j = 1; j <= num; ++j ) 80 cin>>ch[j]; 81 // 接下来选择第num条边以及第1条边来二分答案 82 // 根据三角形中有 C < A+B && C > A-B; 83 double ans = Bsearch( fabs( ch[num] - ch[1] ), ch[1] + ch[num] ); 84 printf( "Case %d: ", i ); 85 if( ans == 0 ) 86 puts( "impossible" ); 87 else 88 printf( "%.3lf\n", ans ); 89 } 90 return 0; 91 }
作者:火星十一郎
本文版权归作者火星十一郎所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.