SP22 TRICENTR - Triangle From Centroid

· · 题解

题目传送门!

更好的阅读体验?

作为一名合格的初中牲,本文出现的所有结论及其证明使用初中数学教材中出现过的内容。如有错误欢迎指正,谢谢!

Update on 2024.10.23 被假数据 Hack 了,重新交一遍。

题意

如图,给出三角形的一条边 BC 和这个三角形的重心 G 到这条边的距离 a 以及到它另外两边的距离 bc,试求这个三角形的面积和它的重心与垂心之间的距离。

本题给定多组数据,第一行输入一个整数 t 表示数据组数,接下来 t 行每行四个浮点数。

解析

1. 三角形面积

这个很简单。如图 1.1 所示,点 D 和点 F 都为中点,由于两个小三角形的高与原三角形相等且底缩小到原来的一半,所以 S_{\Delta FBC} = \frac{1}{2} S_{\Delta ABC}S_{\Delta ABD} = \frac{1}{2} S_{\Delta ABC}。即 S_{\Delta FBC}=S_{\Delta ABD}

根据等式的基本性质,等式两边同时减去公共部分四边形 {FBDG} 的面积,剩余部分面积仍相等。即 S_{\Delta AFG} =S_{\Delta GDC}

\Delta ABG\Delta BGC 中,DF 仍为中点,所以 S_{\Delta AFG} = \frac{1}{2} S_{\Delta ABG} S_{\Delta GDC}= \frac{1}{2} S_{\Delta BGC}。又因为 S_{\Delta AFG} =S_{\Delta GDC},等式两边同时扩大二倍仍相等,即 S_{\Delta ABG} =S_{\Delta BGC}

同理,可证得图中三个中线三角形的面积两两相等,也就是 S_{\Delta ABG} =S_{\Delta BGC}=S_{\Delta CGA}= \frac{1}{3} S_{\Delta ABC}。我们只需要求得其中任意一个三角形的面积即可求得 S_{\Delta ABC}。 题目已经给定了一条边 BC 和重心到这条边的距离 a,很明显 S_{\Delta BGC}=\frac{1}{2} (BC \times a)

所以 S_{\Delta ABC}= 3S_{\Delta BGC} =\frac{3}{2} (BC \times a)

2. 三角形重心到垂心的距离

首先我们来了解一下求两点间距离的公式。如图 1.2,已知 A(x_1,y_1)B(x_2,y_2),要求 AB 的长度,我们就可以先表示图中直角三角形的两条直角边 BCAC。由勾股定理可知,AB=\sqrt{AC^2+BC^2}=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}

double Distance(position A,position B)
{
    double res=(A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
    return sqrt(res);
}

这时我们就可以建立以 B 为原点的坐标系,然后求重心和垂心的坐标。至于为什么用坐标计算,因为用坐标计算可以考虑更全面的情况,从而保证答案正确性。

重心的纵坐标是已知的,即 GH 的长度 a,重点是求重心的横坐标。

如图 1.3,已知 S_{\Delta ABG}=S_{\Delta AGC}=S_{\Delta BGC}=\frac{1}{2}(a \times BC),还知道 bc 的长度,即可求出三角形另外两边 ABAC 的长度。即 AB=(a \times BC)\div bAC=(a \times BC)\div c

三角形重心到一个顶点的距离是到它对边距离的两倍。

连接 EF,因为 EF 都是中点,由中位线定理可知 EF \parallel BCEF=\frac{1}{2} BC。所以 \Delta EFG \sim \Delta BCG,相似比就是 1:2。所以 CG=2FG,证毕。

同理,AG=2KG。此时 \Delta ADK \sim \Delta GHK,相似比为 3:1。于是我们求得了三角形的一条高 ADAD=3 \times a

此时 BD 的长即为 A 的横坐标,同时也是垂心 T 的横坐标。由勾股定理可知,BD=\sqrt{AB^2-AD^2}

观察,此时 \Delta ADK \sim \Delta GHK 仍成立,AD=3 \times a,所以求出 BD=\sqrt{AB^2-AD^2} 后点 A 的横坐标 A_x=-BD,也就是 T_x=-BD

再回到图 1.3,因为上面那个太特殊了。

很显然重心的横坐标 G_x 就是 BH 的长,而 BH=BK-HK。为了便于处理负数,这里的运算将全部使用坐标进行运算。

因为 K 为中点,所以 K_x=BK=\frac{1}{2} BC。又因为 D_x=A_x=T_x,所以 DK=K_x-T_x=\frac{1}{2} BC-T_x。因为 \Delta ADK \sim \Delta GHK,所以 HK=\frac{1}{3} DK=\frac{1}{3}(\frac{1}{2} BC-T_x) =\frac{1}{6} BC-\frac{1}{3} T_x

所以 BH=BK-HK=\frac{1}{2} BC-(\frac{1}{6} BC-\frac{1}{3} T_x)=\frac{1}{3} (BC+T_x)。由于 T_x 处理了负数情况,这个公式在图 1.4 上仍成立。

当点 B 不是坐标系原点时,上述关系仍成立。已知 \Delta ABC 三个顶点的坐标时,三角形重心的坐标即为 G(\frac{x_1+x_2+x_3}{3},\frac{y_1+y_2+y_3}{3})

至此,我们已经求出了三角形重心的横纵坐标及其垂心的横坐标,只差最后一步垂心的纵坐标就完工了。

如图 1.5 所示,垂心的纵坐标 T_y 即为 TD 的长度,可用相似求解。由于等角的余角相等,所以 \angle BAD= \angle BCN。因为 AD 是垂线,所以 \angle ABD= \angle CTD= 90^{\circ},所以 \Delta ABD \sim \Delta CTD \ (AA),所以 BD:AD=TD:CD,所以 TD=(BD \times CD) \div AD

回到图 1.4 的情况,T_x=A_x,当 Ay 轴左侧时很明显 BD 应该取负数,因为这时 T_y 小于零。此时 T_y=-TD=(-BD \times CD) \div AD。之前分类讨论过了 T_x 的取值,我们只需要套用一下 T_x 即可。T_y=(T_x \times (BC-T_x)) \div AD,最后利用两点坐标距离公式求解。

接下来就是你们最喜欢的代码时间了!

AC Code

//970B 10ms 5.10MB C++20
#include<iostream>
#include<cstdio>  
#include<cmath> 
using namespace std;  
int t;//多组数据 
double BC,a,b,c;//已知 
double AD,BF,CE,BD,AE,AF,AT,DT;
struct position{
    double x,y;
    inline void set(int val){x=val; y=val;}
};
inline double Distance(position A,position B)//求两点距离 
{
    double res=(A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
    return sqrt(res);
}
inline bool check(double a,double b,double c)//钝角三角形 
{
    if(b*b>(c*c+a*a)) return 1;
    else return 0;
}
signed main(void)
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf%lf%lf%lf",&BC,&a,&b,&c);
        double S=(BC*a/2.0)*3.0;//面积
        printf("%.3lf ",S);
        double AB=(BC*a)/b,AC=(BC*a)/c;
        position G,T; //重心,垂心 
        T.set(0); G.set(0);
        AD=3*a; //高 
        BD=sqrt(AB*AB-AD*AD);  T.x=BD; 
        if(check(AB,AC,BC))  T.x=-T.x; //钝角三角形   
        G.x=(BC+T.x)/3.0; G.y=a; 
        T.y=T.x*(BC-T.x)/AD;//利用相似求解
        double dis=Distance(T,G);
        printf("%.3lf\n",dis); //距离
    }
    return 0; //完结撒花
}  

AC 记录(最优解第一!)

看来我写了这么长时间的份上,给个赞吧!