0w1

CFR 1 C. Ancient Berland Circus ( Geometry )

Problem - 1C - Codeforces

題意:
有一個正 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;
}