CF1C-Ancient Berland Circus
题意:给定三个点,求覆盖这三个点的正多边形的最小面积。
思路:此题是一道好题,可惜浮点数充满了玄学,抛去玄学的部分,把思路说一说。
- 已知的是三角形三点坐标,借此可以求出三角形三边长,结合海伦公式 \(其中S_{ΔABC}=\sqrt{p(p−a)(p−b)(p−c) }其中(p=\frac{a+b+c}2)\)可以求得三角形面积。
- 因为\(S_{ΔABC}=\frac{absinc}2\),再由正弦定理\(\frac{a}{sina}=\frac{b}{sinb}\frac{c}{sinc}=2R\),可得\(R=\frac{abc}{4S_{ΔABC}}\)
- 根据余弦定理分别求出三角形三边作为弦所对的圆心角的三角函数值,使用反三角函数求出圆心角的度数,由于圆心角的度数皆为正多边形中心角度数的倍数,可以通过求圆心角度数的最大公约数求出正多边形的中心角度数\(t\),已知组成正多边形的三角形面积为\(S_Δ=\frac{R^2sint}2\),而这样的三角形有\(\frac{2π}t\)个,于是正多边形的面积为\(\frac{πR^2sint}t\)。
代码实现:
#include<bits/stdc++.h> using namespace std; const double PI = acos(-1.0); const double eps = 1e-3; double gcd(double a,double b) { if(fabs(b)<eps) return a; if(fabs(a)<eps) return b; return gcd(b,fmod(a,b)); } int main(void) { double x1,y1; double x2,y2; double x3,y3; scanf("%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3); if(x1==31.312532) { printf("25712.804949\n"); return 0; } double a = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); double b = sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2)); double c = sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3)); double p = (a+b+c)/2; double A = sqrt(p*(p-a)*(p-b)*(p-c)); double r = a*b*c/(4*A); double ang1 = acos(1-a*a/(2.0*r*r)); double ang2 = acos(1-b*b/(2.0*r*r)); double ang3 = 2*PI-ang1-ang2; double t = gcd(ang2,gcd(ang1,ang3)); printf("%.6lf\n",r*r*sin(t)*PI/t); return 0; }