給定三角形 ABC 的內切圓半徑 r,以及三個旁切圓半徑 r1, r2, r3(每個旁切圓與兩邊及內切圓相切)。求三角形面積。輸入多組 r, r1, r2, r3,以四個 -1 結束。
設三角形邊長 a,b,c,半周長 p,面積 S。內切圓半徑 r = S/p。
旁切圓半徑 r1 對應邊 a,有 r1 = S/(p-a)。同理 r2 = S/(p-b), r3 = S/(p-c)。
由 r, r1, r2, r3 可解出 p, p-a, p-b, p-c:
p = S/r, p-a = S/r1, p-b = S/r2, p-c = S/r3。
兩邊之和:
a = p - (p-a) = S(1/r - 1/r1),類推 b, c。
但更直接:三角形三邊可由內切圓與旁切圓幾何關係得出:
x1 = sqrt((r+r1)^2 - (r-r1)^2) = 2*sqrt(r*r1) 是內切圓與旁切圓圓心連線在邊上的投影長度?實際推導較複雜,但代碼中採用以下公式:
a1 = sqrt((r+r1)^2 - (r-r1)^2) = 2*sqrt(r*r1)
x1 = a1 * r1 / (r - r1)
同理得 x2, x3
三邊:aa1 = (a1+x1)+(a2+x2), aa2 = (a2+x2)+(a3+x3), aa3 = (a1+x1)+(a3+x3)
面積 = sqrt(q*(q-aa1)*(q-aa2)*(q-aa3)) (海倫公式)
#include <bits/stdc++.h>
using namespace std;
double r[5];
double fun(double r1, double r2) {
return (r1+r2)*(r1+r2) - (r1-r2)*(r1-r2); // = 4*r1*r2
}
bool cmp(double a, double b) { return a > b; }
int main() {
int cas = 1;
while (scanf("%lf%lf%lf%lf", &r[0], &r[1], &r[2], &r[3]) == 4) {
if (r[0] < 0) break;
sort(r, r+4, cmp); // r[0] 為內切圓半徑(最大)
double a1 = sqrt(fun(r[0], r[1]));
double x1 = a1 * r[1] / (r[0] - r[1]);
double a2 = sqrt(fun(r[0], r[2]));
double x2 = a2 * r[2] / (r[0] - r[2]);
double a3 = sqrt(fun(r[0], r[3]));
double x3 = a3 * r[3] / (r[0] - r[3]);
double aa1 = (a1+x1) + (a2+x2);
double aa2 = (a2+x2) + (a3+x3);
double aa3 = (a1+x1) + (a3+x3);
double q = (aa1 + aa2 + aa3) / 2.0;
double S = sqrt(q * (q-aa1) * (q-aa2) * (q-aa3));
printf("Case %d: %.2lf\n", cas++, S);
}
return 0;
}
fun(r1,r2) = 4*r1*r2,所以 a1 = 2*sqrt(r*r1)。本題是幾何公式應用題:已知內切圓與三旁切圓半徑求三角形面積。核心是識別最大半徑為內切圓,套用現成公式計算三邊長再用海倫公式。代碼極短,屬於公式題。