CF1C Ancient Berland Circus

题目链接

题意分析

首先 这是一道数学题

给你一个三角形 求出一个面积最小的正多边形 使得这个三角形的三个点都与其多边形点重合

如果你学过高中数学的话 应该明白 这个三角形与这个多边形共用一个外接圆

先求出三角形三边长\(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;
}
原文地址:https://www.cnblogs.com/tcswuzb/p/14362383.html