小学生一发的刷题之路

(计算几何)

小学生一发

简单的计算几何,求三角形的外接圆以及内切圆的面积。

三角形的外接圆和内切圆面积

题目描述:
给定三个点,分别求出以这三个点形成的三角形的外接圆和内切圆的面积。

输入:
第一行一个整数T,表示数据的组数。
接下来T行,每行6个整数
x1,y1,x2,y2,z1,z2, 分别表示三角形的三个顶点。

输出:
对于每组数据,如果不能形成三角形,输出"NO SOLU
TION",否则输出两个空格分隔的实数,分别表示内切
圆和外接圆的面积。相对误差或者绝对误差在10-6范围
内就认为是正确的。

解析

首先是对输入的三个点判断是否能形成三角形,比较简单的方法是化点为边,把点转化成边来进行计算,分别判断是否有长度为零的边或者满足任意两边之和大于第三边的情况。接着是考虑如何求解外接圆和内切圆的面积。显然要先求出其半径。对于外接圆,可以利用三角形内的正弦定理求出其半径,相应的余弦角在知道三边的情况下可以利用余弦定理即可。对于内切圆,根据内切圆的性质可以利用等面积法来求解其半径,这就需要知道三角形的面积,在知道三边的情况下采用海伦三角形面积公式即可。

AC代码:

//  小学生一发的刷题之路
//  之计算几何
//  求三角形的外接圆和内切圆的面积;
//  海伦三角形面积公式+余弦定理+正弦定理;
//


#include 
#include 
#include 
#include 
#include 
#include 
#include                 //双向队列;
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const double PI=acos(-1.0);
const double eps=1e-8;
const double e=exp(1.0);
const int maxn=1e2+5;
const int maxm=1e6+5;
const ll mod=1e9+7;
const int INF=1e8;
template<class T>
void read(T &ret){              //快速输入模版;
    ret=0;
    int f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        ret=ret*10+c-'0';
        c=getchar();
    }
    ret*=f;
}
struct node{
    double x,y;
    node(){};
}a[3];

double dist(node a,node b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

double solve1(double x,double y,double z){              //外接圆面积;
    double cosa=(x*x+y*y-z*z)/(2*x*y),sina,r;
    sina=sqrt(1-cosa*cosa);
    r=z/(2*sina);       //外接圆半径;
    double ans=PI*r*r;
    return ans;
}

double solve2(double x,double y,double z){              //内切圆面积;
    double s,r,p=(x+y+z)/2.0;
    s=sqrt(p*(p-x)*(p-y)*(p-z));
    r=2*s/(x+y+z);      //内切圆半径;
    double ans=PI*r*r;
    return ans;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        for(int i=0;i<3;i++){
            scanf("%lf %lf",&a[i].x,&a[i].y);
        }
        double x=dist(a[0],a[1]);
        double y=dist(a[1],a[2]);
        double z=dist(a[0],a[2]);
        
        
        if(fabs(x-0)<eps||fabs(y-0)<eps||fabs(z-0)<eps){            //有一边为0的情况;
            cout<<"NO SOLUTION"<<endl;
            continue;
        }else if(fabs(x+y-z)<eps||fabs(x+z-y)<eps||fabs(y+z-x)<eps){
            cout<<"NO SOLUTION"<<endl;
            continue;
        }else{
            double ans1=solve1(x,y,z);
            double ans2=solve2(x,y,z);
            printf("%0.10lf %0.10lf\n",ans2,ans1);
        }
    }
    return 0;
}

新的开始,每天都要快乐哈。
在这里插入图片描述

你可能感兴趣的:(算法类)