C. Ancient Berland Circus(三点确定最小多边形)

题目链接:https://codeforces.com/problemset/problem/1/C

题意:对于一个正多边形,只给出了其中三点的坐标,求这个多边形可能的最小面积,给出的三个点一定能够组成三角形。

思路:根据三角形三个顶点的坐标求得三角形的三边长a、b、c,海伦公式和正弦定理连理得半径R = abc / (4S),再求出外接圆圆心到三角形三个顶点组成的三个圆心角∠1、∠2、∠3的最大公约数作为正多边形的每一份三角形的内角,将所有三角形加起来即可。思路不难但是满满的细节orz,比如防止钝角的情况,边长最长的对应的圆心角 应该这样求: 2*PI - 其他两个圆心角。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const double eps = 1e-4;
 4 const double pi = acos(-1.0);
 5 int sgn(double x)
 6 {
 7     if(fabs(x) < eps) return 0;
 8     else return x < 0 ? -1 : 1;
 9 }
10 double gcd(double a, double b)
11 {
12     if(sgn(b) == 0) return a;
13     if(sgn(a) == 0) return b;
14     return gcd(b, fmod(a,b));
15 }
16 struct Point{
17     double x, y;
18     void input(){
19         scanf("%lf%lf", &x, &y);
20     }
21     double distant(Point p)
22     {
23         double a = (x - p.x);
24         double b = (y - p.y);
25         return sqrt(a * a + b * b);
26     }
27 };
28 double angle(double a, double b, double c)
29 {
30     return acos((a * a + b * b - c * c)/(2.0 * a * b));
31 }
32 
33 int main()
34 {
35     Point point[3];
36     for(int i = 0;i < 3;i++) point[i].input();
37     double a = point[0].distant(point[1]);
38     double b = point[1].distant(point[2]);
39     double c = point[2].distant(point[0]);
40     if(a > c) swap(a, c);
41     if(b > c) swap(b, c);
42     double p = (a + b + c) / 2.0;
43     double S = sqrt(p*(p - a) * (p - b)* (p - c));
44     double r = (a * b * c) /(4.0 * S);
45     double A = angle(r, r, a);
46     double B = angle(r, r, b);
47     double C = 2 * pi - A - B;
48     double ave = gcd(A, gcd(B, C));
49     double ans = r * r * sin(ave)* pi / ave;
50     printf("%.8f\n",ans);
51     return 0;
52 }

 

转载于:https://www.cnblogs.com/Carered/p/11545746.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值