思路
我觉得洛谷上的大多数题解应该有问题,如果我的思路不对请指正,谢谢。
前边题解里说之所以用减去两个角得到第三个角,是因为误差。但其实不是这样的。对于第13个测试点,我把图画出来量出三个角大小并计算正弦值,与程序运行结果相差无几,但是做题的时候直接算确实不行,我们用下图(测试点13)举例:
在算出和之后,之前的题解用来计算的值。但这样得到的并不是真正的的值,而是将关于对称之后得到(因为是正多边形,所以这个必然存在),得到的是的值,这个值明显比原先的更大,求出来三个角的也更大(这里我也不知道为什么,网上也搜不到相关的解释)。
代码
#include<bits/stdc++.h>
#define rep(i,st,ed) for(ll i=st;i<=ed;++i)
using namespace std;
typedef long long ll;
typedef double db;
const db pi=acos(-1);
db x[5],y[5],d[5][5];
struct Line{
db k,b;
};
db dis(db x1,db y1,db x2,db y2)
{
return sqrt(pow(x1-x2,2)+pow(y1-y2,2));
}
db fgcd(db a,db b)
{
if(fabs(a-0.0)<1e-2)
return b;
if(fabs(b-0.0)<1e-2)
return a;
return fgcd(b,fmod(a,b));
}
int main()
{
rep(i,1,3)
scanf("%lf%lf",x+i,y+i);
rep(i,1,3)
rep(j,i+1,3)
d[i][j]=dis(x[i],y[i],x[j],y[j]);
db KAB=(y[1]-y[2])/(x[1]-x[2]);
db KAC=(y[1]-y[3])/(x[1]-x[3]);
db KAB_=(db)(-1)/KAB;
Line AB_={KAB_,(y[1]+y[2])/2-KAB_*(x[1]+x[2])/2};
db KAC_=(db)(-1)/KAC;
Line AC_={KAC_,(y[1]+y[3])/2-KAC_*(x[1]+x[3])/2};
x[0]=(AB_.b-AC_.b)/(AC_.k-AB_.k);
y[0]=KAB_*x[0]+AB_.b;
db R=dis(x[0],y[0],x[1],y[1]);
db C_AB=2.0*asin(d[1][2]/2.0/R);
db C_AC=2.0*asin(d[1][3]/2.0/R);
//db C_BC=2.0*asin(d[2][3]/2.0/R);
db C_BC=2.0*pi-C_AB-C_AC;
//printf("%lf %lf %lf\n",C_AB,C_AC,C_BC);
db Cir=fgcd(fgcd(C_AB,C_AC),C_BC);
db S=R*R/2.0*sin(Cir);
db n=2*pi/Cir;
printf("%.8lf",n*S);
}