CF 1C

题目大意是给出正多边形上的三个点坐标, 求这个正多边形的面积.
由于是确定是正多边形,所以一定存在外接圆.所以可以分为如下几步:
海伦公式: p=(a+b+c)/2      S=√p(p-a)(p-b)(p-c)
1.求外接圆半径r=abc/4S
2.由余弦定理求出三个圆心角ang[3]
(要注意的是,有可能有三个点在同一段半圆弧上,这是第三个圆心角应该用2π-ang[0]-ang[1], 所以干脆全部都是ang[2]=2π-ang[0]-ang[1])
3.求这三个角的最大公约数为A, 那么这就是一个正2π/A边形.
4.一个小三角形的面积S=1/2·r * r * sinA
5.nS即为所求.
/* ********************************************** Auther: 请叫我acm渣渣 Created Time: 2015-7-29 12:52:06 File Name : h.cpp *********************************************** */
#include <iostream>
#include <fstream>
#include <cstring>
#include <climits>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <utility>
#include <sstream>
#include <complex>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <bitset>
#include <functional>
#include <algorithm>
using namespace std;
#define lson L,m,rt<<1
#define rson m+1,R,rt<<1|1
#define ll long long
#define N 11111
const double  PI=3.1415926535;
const double eps = 1e-2;

double x[4],y[4];

double d[4];

double dis(double x1,double y1,double x2,double  y2){
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

double fgcd(double  a,double b){
    if(a<eps&&a>-eps) return b;
    if(b<eps&&b>-eps) return a;
    return fgcd(b,fmod(a,b));
}

int main(){
    for(int i=0;i<=2;i++) scanf("%lf%lf",&x[i],&y[i]);
    for(int i=0;i<=2;i++) d[i] = dis(x[i],y[i],x[(i+1)%3],y[(i+1)%3]);

    double p = (d[0]+d[1]+d[2])/2;

    double s = sqrt(p*(p-d[0])*(p-d[1])*(p-d[2]));

    double r = d[0]*d[1]*d[2]/(s*4);

    double ang[3];
    for(int i=0;i<3;i++) ang[i] = acos(1-d[i]*d[i]/(2*r*r));
    ang[2] = 2*PI - ang[0] - ang[1];

    double ok = 0;
    for(int i=0; i<3;i++) ok  = fgcd(ok,ang[i]);

    printf("%.6f\n",r*r*sin(ok)*PI/ok);
}

你可能感兴趣的:(CF 1C)