题目链接
题意分析
首先 这是一道数学题
给你一个三角形 求出一个面积最小的正多边形 使得这个三角形的三个点都与其多边形点重合
如果你学过高中数学的话 应该明白 这个三角形与这个多边形共用一个外接圆
先求出三角形三边长\(a,b,c\) 然后通过海伦公式求出面积\(S_{abc}=\sqrt{p(p-a)(p-b)(pc)},p=\frac{a+b+c}{2}\)
由于正弦定理\(\frac{a}{sinA}=\frac{b}{sinB}=\frac{c}{sinC}=2R\)
所以\(\frac{a}{sinA}=\frac{abc}{2S_{abc}}=2R\) 即\(\frac{abc}{4S_{abc}}=R\)
然后我们求出了外接圆的半径\(R\)
然后使用余弦定理加上反三角函数 \(cosθ=\frac{2R^2-a^2}{2R^2}=1-\frac{a^2}{2R^2}\)
我们就可以求出三条线对应的圆心角的值 然后求出最大公约数\(t\) 就是最小的正多边形的一条边对应的圆心角
最小的正多边形一条边加上两条半径组成一个三角形 面积为\(s=\frac{R^2sint}{2}\)
同时一共存在\(\frac{2π}{t}\)个 那么这个多边形的面积就是\(S=\frac{πR^2sint}{t}\)
一些细节
我们还要注意 这是一道浮点数题 自然而然就是一道卡精度题
1.\(π=arccos(-1)\) 这比直接yy一个要准确很多
2.求浮点数的最大公约数 需要特殊的gcd函数
double gcd(double x,double y)
{
if(fabs(y)<eps) return x;
if(fabs(x)<eps) return y;
return gcd(y,fmod(x,y));//fmod用于计算浮点类型下的x%y
}
3.为了防止误差 计算三个圆心角的时候 \(A,B\)正常计算 \(C=2π-A-B\)
CODE:
#include<bits/stdc++.h>
#define eps 1e-3
using namespace std;
const double Pi=acos(-1.0);
double ax,ay,bx,by,cx,cy;
double la,lb,lc,p;
double Sabc,R;
double A,B,C;
double getdis(double xa,double ya,double xb,double yb)
{return sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb));}
double gcd(double x,double y)
{
if(fabs(y)<eps) return x;
if(fabs(x)<eps) return y;
return gcd(y,fmod(x,y));
}
int main()
{
scanf("%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&cx,&cy);
la=getdis(ax,ay,bx,by);
lb=getdis(bx,by,cx,cy);
lc=getdis(ax,ay,cx,cy);
p=(la+lb+lc)/2.0;
Sabc=sqrt(p*(p-la)*(p-lb)*(p-lc));
R=(la*lb*lc)/(4.0*Sabc);
// printf("now R is %.8lf\n",R);
A=acos(1.0-(la*la)/(2*R*R));
B=acos(1.0-(lb*lb)/(2*R*R));
C=2*Pi-A-B;
// printf("%.8lf %.8lf %.8lf\n",A,B,C);
double tmp=gcd(A,gcd(B,C));
// printf("now is %.8lf\n",tmp);
printf("%.6lf\n",(Pi/tmp)*R*R*sin(tmp));
return 0;
}