欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ZOJ - 3806 Incircle and Circumcircle(计算几何+二分)

程序员文章站 2022-04-01 09:37:48
...

点我看题

题意:给出三角形的内切圆和外接圆的半径,判断是否存在满足这样条件的三角形,如果存在的话,输出满足条件的任意一个三角形的三边的长度。

分析:如果单纯的用内切圆外接圆和三角形的关系公式的话,是得不到结果的。首先我们考虑,要怎么判断是否存在这样的一个三角形呢?三角形的极端情况就是等边三角形,对于一个等边三角形来说,他的内切圆半径最大,外接圆半径最小,且内切圆的半径为外接圆半径的1/2,这个时候如果外接圆半径r1>内切圆半径r2/2那么就不存在满足条件的三角形。当r1<=r2/2时,利用二分来求解。先把要求解的三角形抽象为等腰三角形,设底边长度为a,腰为c,通过不断二分底边长度(极端情况l=0,r=等边三角形的长),根据内切圆和外接圆求得腰的长度,然后不断逼近答案。

//纯高中数学+二分哇

//输出的小数点个数在8以上应该都可以,没有固定要求

参考代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<algorithm>

using namespace std;
#define eps 1e-8
double r1,r2;//r1为内切圆半径,r2为外接圆半径

int main()
{
    while( ~scanf("%lf%lf",&r1,&r2))
    {
        if( r1-r2/2 > eps)
        {
            puts("NO Solution!");
            continue;
        }
        else
        {
            double l = 0;
            double r = sqrt(3.0)*r2;
            double mid,a1,h1,a2,h2;
            while( r-l >= eps)
            {
                mid = (l+r)/2.0;
                h1 = r2+sqrt(r2*r2-mid*mid/4.0);
                a1 = sqrt(h1*h1+mid*mid/4.0);
                h2 = sqrt(r1*r1+(a1-mid/2.0)*(a1-mid/2.0))+r1;
                a2 = sqrt(h2*h2+mid*mid/4.0);
                if( a2 - a1 < eps)
                    r = mid;
                else
                    l = mid;
            }
            printf("%.10f %.10f %.10f\n",a1,a1,mid);
        }
    }

    return 0;
}