余弦公式+海伦公式+浮点数gcd——cf1C

注意:对浮点数进行gcd时尽量吧eps设得大一点1e-2

/*
当圆外切给定三角形时,该圆最小
求三角形ABC外切圆的半径R
    S=0.5*ab*sinC
    a/sinA = b/sinB = c/sinC = 2R
        S=abc/4R => R=abc/4S
    根据海伦公式 S=sqrt(p(p-a)(p-b)(p-c))即可算出S

然后再求圆内多边形面积
    把每条边对应的圆心角通过acos求出来, 
    然后求gcd找到最大的单位角 
     
*/
#include<bits/stdc++.h>
using namespace std;

typedef double db;
const db eps=1e-2;
const db pi=acos(-1);
int sign(db k){
    if (k>eps) return 1; else if (k<-eps) return -1; return 0;
}
int cmp(db k1,db k2){return sign(k1-k2);}

struct point{
    db x,y;
    point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
    point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
    point operator * (db k1) const{return (point){x*k1,y*k1};}
    point operator / (db k1) const{return (point){x/k1,y/k1};}
    int operator == (const point &k1) const{return cmp(x,k1.x)==0&&cmp(y,k1.y)==0;}
    db abs(){return sqrt(x*x+y*y);}
    db abs2(){return x*x+y*y;}
    db dis(point k1){return ((*this)-k1).abs();}
};

point p[3];
db len[3],rad[3];
db S,pp,R,unit,unitS;

double gcd(db a, db b){
    if(fabs(b)<eps)return a;
    if(fabs(a)<eps)return b;
    return gcd(b,fmod(a,b));
}

int main(){
    for(int i=0;i<3;i++)
        cin>>p[i].x>>p[i].y;
    len[0]=p[0].dis(p[1]);
    len[1]=p[1].dis(p[2]);
    len[2]=p[2].dis(p[0]);
    pp=len[0]+len[1]+len[2];
    pp*=0.5;
    
    S=sqrt(pp*(pp-len[0])*(pp-len[1])*(pp-len[2]));
    R=len[0]*len[1]*len[2]/4/S;
    
    sort(len,len+3);
    rad[0]=acos((2*R*R-len[0]*len[0])/(2*R*R));
    rad[1]=acos((2*R*R-len[1]*len[1])/(2*R*R));
    rad[2]=2*pi-rad[0]-rad[1];
    
    unit=rad[0];
    unit=gcd(unit,rad[1]);
    unit=gcd(unit,rad[2]);
    
    int num=2*pi/unit;
    printf("%.6lf\n",pi*R*R*sin(unit)/unit);
}
/*
17.288379 68.223317
48.776683 71.688379
23.170559 106.572762
*/ 
原文地址:https://www.cnblogs.com/zsben991126/p/12357075.html