[poj1927]Area in Triangle--计算几何

题目描述

Given a triangle field and a rope of a certain length (Figure-1), you are required to use the rope to enclose a region within the field and make the region as large as possible.

Input

The input has several sets of test data. Each set is one line containing four numbers separated by a space. The first three indicate the lengths of the edges of the triangle field, and the fourth is the length of the rope. Each of the four numbers have exactly four digits after the decimal point. The line containing four zeros ends the input and should not be processed. You can assume each of the edges are not longer than 100.0000 and the length of the rope is not longer than the perimeter of the field.

Output

Output one line for each case in the following format:

Case i: X

Where i is the case number, and X is the largest area which is rounded to two digits after the decimal point.

Sample Input

12.0000 23.0000 17.0000 40.0000
84.0000 35.0000 91.0000 210.0000
100.0000 100.0000 100.0000 181.3800
0 0 0 0

Sample Output

Case 1: 89.35
Case 2: 1470.00
Case 3: 2618.00

题解

这道题目的大概意思就是给你一个三角形的三条边和一根绳子的长度,问你将绳子放在三角形里围出来的最大面积是多少。

这道题目可以说是计算几何的基础过关吧,用到了不少知识。。。。

首先我们可以分三种情况来讨论:

1.如果绳子的长度要比三角形的周长还要长的话,那么答案就肯定是三角形的面积

2.如果绳子的长度要比三角形的内接圆的周长还要小,那么答案就是这个长度的绳子可以围成的圆的面积

3.那么对于剩下的,我们实际上可以发现实际上那个绳子实际上把三角形割成了三个角,而且那三条割线是三条圆弧,如下图所示
这里写图片描述

实际上我们割的最优方案就是那个红线的位置,现在我们考虑怎么算它。

首先,通过一些基本的角度运算我们就可以发现,实际上那三个角的三段圆弧实际上可以拼起来成为一个圆。那我们就可以像上图一样,将两个角移到另一个角旁边去,这样就会出现大小三角形和大小圆,而显然他们相似并且相似比相同。所以我们要算的答案实际上变成了:

大三角形面积-小三角形面积+小圆面积

所以我们实际上就只需要知道它们的相似比就行了。那么相似比怎么算呢?

我们可以知道:三角形的周长-线的长度=小三角形周长-小圆周长

于是我们就把大三角形的周长和大圆的周长算出来,那么相似比就出来了。

然后我们再用相似比求出小圆面积和小三角形面积,再带到上面那个式子里去就可以了。

下面我讲一些在这道题中比较难算的东西:
1.大三角形面积:大三角形面积可以首先利用余弦公式求出一个角的余弦,然后通过一个很显然的公式 s i n 2 A + c o s 2 B = 1 可以求出一个角的正弦,然后通过公式 S = 1 2 a b × s i n C 可以得到面积
2.三角形的内切圆半径:可以用三角形的面积*2/三角形的周长得到,至于原因,因为三角形的内心到三边的距离都相等嘛。。。

然后这道题目就讲完了。下面贴代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstring>
#include<cmath>
#define pi acos(-1.0)
using namespace std;
double solve(double a,double b,double c,double d)
{
    double L=a+b+c;
    double cosC=(a*a+b*b-c*c)/(2*a*b);
    double S=0.5*a*b*(sqrt((double)1-cosC*cosC));
    double r=S*2/L;
    if(d>L){
        return S;
    }
    if(2*pi*r>=d){
        return (d*d)/(4*pi);
    }
    double bi=(L-d)/(L-2*pi*r);
    double rx=r*bi;
    return S-S*bi*bi+pi*rx*rx;
}
int main()
{
    double a,b,c,d;
    int cnt;
    while(~scanf("%lf%lf%lf%lf",&a,&b,&c,&d))
    {
        if(a==0&&b==0&&c==0&&d==0)  break;
        printf("Case %d: %.2f\n",++cnt,solve(a,b,c,d));
    }
    return 0;
}

感谢大家看我的博客。。。谢谢!
有什么问题可以直接在下面提,感激不尽!

猜你喜欢

转载自blog.csdn.net/dark_dawn/article/details/81349364