Codeforces Beta Round #1 C. Ancient Berland Circus 题解

649 阅读2分钟

题目链接

思路

我觉得洛谷上的大多数题解应该有问题,如果我的思路不对请指正,谢谢。
前边题解里说之所以用2π2\pi减去两个角得到第三个角,是因为误差。但其实不是这样的。对于第13个测试点,我把图画出来量出三个角大小并计算正弦值,与程序运行结果相差无几,但是做题的时候直接算确实不行,我们用下图(测试点13)举例:
测试点13对应的图
在算出AOB∠AOBAOC∠AOC之后,之前的题解用2πAOBAOC2\pi-∠AOB-∠AOC来计算BOC∠BOC的值。但这样得到的并不是真正的BOC∠BOC的值,而是将CC关于OAOA对称之后得到CC'(因为是正多边形,所以这个CC'必然存在),得到的是BOC∠BOC'的值,这个值明显比原先的BOC∠BOC更大,求出来三个角的gcdgcd也更大(这里我也不知道为什么,网上也搜不到相关的解释)。

代码

#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);
}