zoukankan      html  css  js  c++  java
  • CodeForces

    CodeForces - 1C

    题目大意:

    给出一个正(N)多边形的三个点,问其最小可能面积是多少。

    思路:

    多边形各个点肯定都在外接圆上,并且边越多越接近外接圆的面积,因此我们考虑选取尽可能少的边数。

    已知三角形ABC三点坐标,可以求出该三角形三边边长,借助海伦公式可以得到(S_{Delta ABC})

    假设有一个三角形,边长分别为(a)(b)(c),三角形的面积(A)可由以下公式求得:

    $ A = sqrt{s * (s - a) * (s - b) * (s - c)} $ ,其中 (s = frac{a + b + c}{2})

    该三角形的外接圆半径$ R = frac{abc}{4S} $。

    根据余弦定理(cos A = frac{b^2 + c^2 - a^2}{2bc})可以求出该三角形三个圆心角三角函数值,使用反三角函数(acos())可以得到度数,因为圆心角的度数必为正多边形中心角的整数倍,所以求三者的(gcd)即可得到中心角度数(α)

    易得(任取其中一个非外接圆圆心的顶点做一条垂线)组成正多边形的三角形的面积为(S_{Delta}=frac{R^{2}sin alpha}{2}),三角形个数为(frac{2pi}{alpha }),所以该正多边形最小面积为(S_{min} = frac{pi R^2 sin alpha}{alpha})

    code:
    #include <bits/stdc++.h>
    using namespace std;
    const double eps = 1e-4;
    const double PI = acos(-1.0);
    
    double sq(double x) { return x * x; }
    double gcd(double a, double b) {
        if (a < eps) return b;
        if (b < eps) return a;
        return gcd(b, fmod(a, b));
    }
    
    int main() {
        ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        double x1, y1, x2, y2, x3, y3; cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
        double a = sqrt(sq(x1 - x2) + sq(y1 - y2));
        double b = sqrt(sq(x2 - x3) + sq(y2 - y3));
        double c = sqrt(sq(x1 - x3) + sq(y1 - y3));
        //海伦公式
        double s = (a + b + c) / 2;
        double A = sqrt(s * (s - a) * (s - b) * (s - c));
        double r = a * b * c / 4.0 / A;
        //计算圆心角
        double Alpha = acos((2 * sq(r) - sq(a)) / 2.0 / r / r);
        double Beta = acos((2 * sq(r) - sq(b)) / 2.0 / r / r);
        double Gamma = 2 * PI - Alpha - Beta;
    
        double sta = gcd(Alpha, gcd(Beta, Gamma)); //取最大公约数即为中心角
        double S_min = sin(sta) * (PI / sta) * sq(r);
        cout << fixed << setprecision(8) << S_min << endl;
        return 0;
    }
    

    (tips)

    • 三角形面积公式可以采用行列式形式求减少精度损失。
    • (eps)精度取太高会导致对圆心角的要求更高,边数增多引起面积变大。
    • 由于(double)的精度问题我们需要使用(Gamma = 2 * PI - Alpha - Beta)来计算最大的那个角的度数。
    • (fmod(x, y)) 返回(double) (x) (/) (double) (y) 的余数
  • 相关阅读:
    linux上搭建tingproxy服务
    windows上搭建linux系统
    PHP将图片流存为图片文件
    openLayer矩形框选要素,展示要素属性
    点击选中的要素,更换标注图片,并添加文本标注
    openLayer点击要素获取对应的属性信息
    openLayer实现放大缩小
    openLayer的切换中心点、定位功能
    使用openLayer加载arcgis中的地图
    openLayer实现两个地图联动
  • 原文地址:https://www.cnblogs.com/Nepenthe8/p/13674404.html
Copyright © 2011-2022 走看看