問題ページ
問題文
現在では、バーランドの円型競技場は、直径13mの円型アリーナを持っていますが、昔はそうではありませんでした。
古代バーランドの円方競技場のアリーナの形は正多角形でした。その大きさと角度はそれぞれの闘技場によって異なりました。アリーナの全ての角には特別な柱がありました。ロープが柱同士を結んでアリーナの辺になっていました。
最近、バーランドの科学者は古代の闘技場の形跡を発見しました。彼らは3本の柱のみを発見することができました。それ以外の柱は時間経過により破壊されていました。
あなたはそれらの3本の柱の座標が与えられるので、そのアリーナが持っていたと考えられる最小の面積を出力してください。
制約
- 座標の絶対値は1000を超えない。
解法
↓反転
正多角形の頂点は外接円の円周にある。外接円の中心求めてあとはシミュレーション。
#include <iostream> #include <cmath> #include <cstdio> #include <vector> #include <complex> using namespace std; typedef complex<double > P; const double EPS = 1e-5; const double PI = asin(0.5) * 6; P getCircumcenter(P a,P b,P c){ double A1 = 2 * ( b.real() - a.real() ); double B1 = 2 * ( b.imag() - a.imag() ); double C1 = pow(a.real(),2)-pow(b.real(),2) + pow(a.imag(),2)-pow(b.imag(),2); double A2 = 2 * ( c.real() - a.real() ); double B2 = 2 * ( c.imag() - a.imag() ); double C2 = pow(a.real(),2)-pow(c.real(),2) + pow(a.imag(),2)-pow(c.imag(),2); double X = (B1 * C2 - B2 * C1) / (A1 * B2 - A2 * B1); double Y = (C1 * A2 - C2 * A1) / (A1 * B2 - A2 * B1); return P(X,Y); } double AreaOfPolygon(vector<P> p){ double S = 0 ; p.push_back(p[0]); for(int i = 0 ; i < p.size()-1 ; i++){ S += (p[i].real() - p[i+1].real()) * (p[i].imag()+p[i+1].imag()); } S /= 2.0; return S; } int same(P a,P b){ return abs(a-b) < EPS; } int main(){ int n; P a,b,c; cin >> a.real() >> a.imag() >> b.real() >> b.imag() >> c.real() >> c.imag(); P g = getCircumcenter(a,b,c); a -= g; b -= g; c -= g; double R = abs(a); double f = atan2(a.imag(),a.real()); for(int i = 3 ; ; i++){ double r = (2*PI) / i; int B = 0; vector<P> add; for(int j = 0 ; j < i ; j++){ double t = f + (j * r); double x = R * cos(t) , y = R * sin(t); if(same(P(x,y),a)) B |= 1; else if(same(P(x,y),b)) B |= 2; else if(same(P(x,y),c)) B |= 4; add.push_back(P(x,y)); } if(B==7){ printf("%.10f\n",AreaOfPolygon(add)); return 0; } } }