小学生一发的刷题之路

(计算几何)

小学生一发

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

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

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

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

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

解析

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

AC代码:

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


#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <deque>                //双向队列;
#include <cmath>
#include <set>
#include <stack>
#include <map>
#include <vector>
#include <cstdlib>
#include <iomanip>
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;
}

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

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值