CFR 1 C. Ancient Berland Circus ( Geometry )
題意:
有一個正 N 邊形,給你其中三個點,問最小可能面積。
制約:
保證最佳的 N 不超過 100。
解法:
用餘弦定理求的三個角分別多少。
用正弦定理求外接圓半徑。
枚舉 N,如果三個圓心角都是 360 度 / N 的整數倍,那麼就能直接算出面積。
不懂:
EPS 調緊一點點的話,就算 long double 也會爛掉。
#include <bits/stdc++.h> using namespace std; const double PI = acos( -1.0 ); const double EPS = 1e-6; double Px[ 3 ], Py[ 3 ]; double len[ 3 ]; double angle[ 3 ]; double yuxian( double a, double b, double c ) { // returns C return acos( ( a * a + b * b - c * c ) / ( 2.0 * a * b ) ); } signed main() { ios::sync_with_stdio( 0 ); for( int i = 0; i < 3; ++i ) { cin >> Px[ i ] >> Py[ i ]; } for( int i = 0; i < 3; ++i ) { auto sqr = [ & ]( double x ) { return x * x; }; len[ i ] = sqrt( sqr( Px[ ( i + 1 ) % 3 ] - Px[ ( i + 2 ) % 3 ] ) + sqr( Py[ ( i + 1 ) % 3 ] - Py[ ( i + 2 ) % 3 ] ) ); } for( int i = 0; i < 3; ++i ) { angle[ i ] = yuxian( len[ ( i + 1 ) % 3 ], len[ ( i + 2 ) % 3 ], len[ i ] ); } double R = len[ 0 ] / sin( angle[ 0 ] ) / 2.0; for( int i = 3; ; ++i ) { double base = 2.0 * PI / i; int xisu = 0; for( int j = 0; j < 3; ++j ) { xisu += int( ( 2.0 * angle[ j ] + EPS ) / base ); // 2 bei de yuan xin jiao } if( fabs( xisu * base - 2.0 * PI ) < EPS ) { cout << fixed << setprecision( 9 ) << i * R * R * sin( base ) / 2.0 << endl; exit( 0 ); } } return 0; }