codeforces 1C-Ancient Berland Circus

题意

给定一个正多边形的三个顶点,求这个正多边形的最小面积

题解

确定多边形的任意三点组成的三角形的外接圆与多边形的外接圆相同,而正多边形的边数越多,越接近外接圆,面积越大,即问题转化问求多边形的最大边数,之后利用多边形公式即可求出。

  1. 已知三个点坐标x,y,z,并通过xyz三点优先计算其三条边a,b,c
  2. 通过海伦公式计算三角形的面积S
  3. 通过三角形外接圆与多边形外接圆相同可知,利用外接圆半径公式计算外接圆的半径R
  4. 已知边长abc,可求出对应角ABC的大小
  5. 此时需要求多边形的边数n,此时需要与已知信息进行联系,设n边形其中一边的圆心角为θ,即n=2π/θ,要使得n最大,则θ要最小
    1. 由于xyz均为正n边形上的一点且不连续,则abc对应的圆心角设为αθ,βθ,γθ,其中α,β,γ均为整数
    2. 圆周角定理:一条弧所对圆周角等于它所对圆心角的一半。可知θ=2π/n,即圆心角αθ=2A, βθ=2B, γθ=2C,要使得ABC均能整除θ,则θ为GCD(A,B,C)的倍数,由于θ最小,则θ为2xGCD(A,B,C),则n=π/θ
  6. 此时需要计算多边形的面积Area

知识点

  • 两点之间的距离公式
    A B = ( x 2 x 1 ) 2 + ( y 2 y 1 ) 2 |AB|=\sqrt{{(x_2 - x_1)}^2 + {(y_2 - y_1)}^2}

  • 海伦公式: p=(a+b+c)/2
    S = p ( p a ) ( p b ) ( p c ) S=\sqrt { p(p-a)(p-b)(p-c) }

  • 外接圆半径:
    R = a b c 4 S R=\frac {a*b*c} {4*S}

  • 正多边形面积计算公式:
    A r e a = 1 2 n r 2 s i n φ Area=\frac12nr^2sin\varphi

  • 浮点数取模:
    也可以使用代码中的方法

double gcd(double x, double y) {
    while (fabs(x) > eps && fabs(y) > eps) {
        if (x > y)  x -= floor(x / y) * y;
        else y -= floor(y / x) * x;
    }
    return x + y;
}
//eps = 1e-4

代码

#include <cstdio>
#include <cmath>
using namespace std;
#define eps 1e-4
#define Pi  acos(-1)

double gcd(double x,double y){
    return fabs(y)<1e-4?x:gcd(y,fmod(x,y));
}

double f(double ax,double ay,double bx,double by){
    return sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));
}
int main(){
    double x[3],y[3];
    for(int i=0;i<3;i++) scanf("%lf%lf",&x[i],&y[i]);
    double a=f(x[0],y[0],x[1],y[1]);
    double b=f(x[1],y[1],x[2],y[2]);
    double c=f(x[0],y[0],x[2],y[2]);
    double p=(a+b+c)/2.0;
    double s=sqrt(p*(p-a)*(p-b)*(p-c));
    double r=a*b*c/(s*4);
    double A=acos((b*b+c*c-a*a)/(2.0*b*c));
    double B=acos((c*c+a*a-b*b)/(2.0*a*c));
    double C=acos((a*a+b*b-c*c)/(2.0*a*b));
    double o=gcd(gcd(A,B),C);
    double n=Pi/o;
    printf("%.8lf\n",n/2.0*r*r*sin(2*Pi/n));
    return 0;
}
发布了64 篇原创文章 · 获赞 3 · 访问量 6230

猜你喜欢

转载自blog.csdn.net/qazsatan/article/details/102814455
今日推荐