当前位置: 首页 > 工具软件 > Circus > 使用案例 >

【CF1C】 Ancient Berland Circus

胡意致
2023-12-01

题目

题意翻译
现在所有的马戏团在 Berland 都有一个直径13米的圆形竞技场, 但在过去的事情是不同的。

在古代 Berland 竞技场的马戏团被塑造成一个规则 (等角) 多边形, 角色的大小和角度可能因马戏团而异。竞技场的每个角落都有一根特别的柱子, 柱子之间的绳子标记着竞技场的边缘。

最近, 来自 Berland 的科学家发现了古代马戏团竞技场的遗迹。他们发现只有三根柱子, 其他的被毁坏了

你得到了这三根柱子的坐标。请找出竞技场中最小的区域。

输入三行,每行包含两个数字,表示柱子的坐标,坐标的绝对值不超过1000,小数点后不超过6位。

输出古代竞技场的可能的最小区域面积,精确到小数点后至少6位,保证在最佳答案中多边形角的数目不大于100。

题目描述
Nowadays all circuses in Berland have a round arena with diameter 13 meters, but in the past things were different.

In Ancient Berland arenas in circuses were shaped as a regular (equiangular) polygon, the size and the number of angles could vary from one circus to another. In each corner of the arena there was a special pillar, and the rope strung between the pillars marked the arena edges.

Recently the scientists from Berland have discovered the remains of the ancient circus arena. They found only three pillars, the others were destroyed by the time.

You are given the coordinates of these three pillars. Find out what is the smallest area that the arena could have.

输入输出格式
输入格式:
The input file consists of three lines, each of them contains a pair of numbers –– coordinates of the pillar. Any coordinate doesn’t exceed 1000 by absolute value, and is given with at most six digits after decimal point.

输出格式:
Output the smallest possible area of the ancient arena. This number should be accurate to at least 6 digits after the decimal point. It’s guaranteed that the number of angles in the optimal polygon is not larger than 100.

输入输出样例
输入样例#1:
0.000000 0.000000
1.000000 1.000000
0.000000 1.000000
输出样例#1:
1.00000000

思路

其实是一道计算几何。

我们首先考虑,对于给出的三个正多边形顶点,两两连边之后,中垂线交于正多边形所在圆心的中点——显然。那么我们可以凭此求出圆心和半径。

之后对于该多边形,我们考虑,由于其让求的正多边形需要面积最小,并且对于给出的三个点,由于在正多边形上的原因,所以都应该是该正多边形相邻两个顶点在外接圆上所对的圆心角的整数倍

那么我们就做一个double类型的gcd就好了——因为在外接圆大小一定时(三点已确定一个圆),对于正n边形,其面积与n成正相关。所以取gcd一定是个最好的选择。

最后的面积嘛…大概只需要余弦定理一下就好。此处借鉴的是第一篇题解里面求面积的方法——提醒一句:第三个角必须yong2π减去另外两个角得到,如果不这样误差会相当的大……尤其是乘上一堆之后,面积会很不精确qaq

代码

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<string.h>
#include<algorithm>
using namespace std;
const double pi=3.1415926;//π
double mod(double a,double b)//小数取模
{
  return a-(int)(a/b)*b;
}
double gcd(double x,double y)//小数gcd
{
  if(y<=0.0001)return x;
  return gcd(y,mod(x,y));
}
double x,y,x2,y2,x3,y3;
int main()
{
  cin>>x>>y>>x2>>y2>>x3>>y3;
  //计算三角形三条边长
  double a=sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));
  double b=sqrt((x-x3)*(x-x3)+(y-y3)*(y-y3));
  double c=sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3));
  double p=(a+b+c)/2;
  double r=(a*b*c)/(4*sqrt(p*(p-a)*(p-b)*(p-c)));//通过r=(abc)/(4s)得出外接圆半径
  //分别求出以三条边为低,外接圆半径为腰的三角形的顶角角度
  double angle1=acos(1-(a*a)/(2*r*r));
  double angle2=acos(1-(b*b)/(2*r*r));
  double angle3=2*pi-angle1-angle2;
  double angle=gcd(angle1,gcd(angle2,angle3))/pi*180;//题目所示的以正多边形边长为低接圆半径为腰的三角形的顶角角度
  double side=sqrt(2*r*r-2*r*r*cos(angle/180*pi));//求出正多边形的边长
  double P=(r*2+side)/2;
  double s=sqrt(P*(P-r)*(P-r)*(P-side))/*三角形面积*/*(360/angle)/*三角形个数*/;//计算面积
  cout<<fixed<<setprecision(6)<<s;//保留6位小数输出
  return 0;
}
 类似资料:

相关阅读

相关文章

相关问答