题解:P9423 [蓝桥杯 2023 国 B] 数三角

· · 题解

P9423:数三角 题解

分析

这题其实并不难,直接枚举选取的三个点,求它们间的距离,判断是否组成等腰三角形,如果是答案就加 1,最后输出答案。

要点 1:两点之间距离公式

设第一个点为 A,第二个点为 BA_xA 点的 x 坐标,A_yA 点的 y 坐标,则 AB 间的距离为:

\sqrt{(A_x-B_x)^2+(A_y-B_y)^2}

写成代码如下:

double jl(int v1,int v2){
    return double(sqrt((x[v1]-x[v2])*(x[v1]-x[v2])+(y[v1]-y[v2])*(y[v1]-y[v2])));
}

要点 2:排除枚举重复的情况

在枚举三个点时,我们需要排除重复的情况,让答案不会重复累加一种组合。因此,我们的循环需要写成这样:

for(int i=0;i<n;i++){
  for(int j=i;j<n;j++){
    for(int k=j;k<n;k++){
      //代码
    }
  }
}

要点 3:判断

既然是等腰三角形,那么我们最先想到的应该是有两条边相等吧。没错,这是一个要求。可是有些人往往会忽略一个最基本的要求:能够组成三角形!

所以,我们需要先判断这三个点是否可以组成三角形:

三角形的性质:任意两条边的和大于第三边。

然后再判断是否有两条及以上的边相等。代码如下:

if(jl(i, j)+jl(i, k)>jl(j, k)&&jl(i, k)+jl(j, k)>jl(i, j)&&jl(j, k)+jl(i, j)>jl(k, i)){//是否可以组成三角形
  if((jl(i, j)==jl(j, k))||(jl(i, k)==jl(i, j))||(jl(i, k)==jl(j, k)))/*是否有两条边相等*/cnt++;
}

完整代码

#include <iostream>
#include <cmath>
using namespace std;
int x[2005],y[2005];//每个点的x坐标和y坐标
double jl(int v1,int v2){//如要点1,两点间的距离,直接导入两个点的编号
    return double(sqrt((x[v1]-x[v2])*(x[v1]-x[v2])+(y[v1]-y[v2])*(y[v1]-y[v2])));//懒得写pow了,当然也可以
}
int main(){
    int cnt=0;//答案计数器
    int n;//点个数
    cin>>n;
    for(int i=0;i<n;i++){//循环输入每个点的坐标
        cin>>x[i]>>y[i];
    }
    for(int i=0;i<n;i++){//1号点
        for(int j=i;j<n;j++){//2号点,j=i如要点2
            for(int k=j;k<n;k++){//3号点,k=j如要点2
                if(jl(i, j)+jl(i, k)>jl(j, k)&&jl(i, k)+jl(j, k)>jl(i, j)&&jl(j, k)+jl(i, j)>jl(k, i)){//是否组成三角形
                    if((jl(i, j)==jl(j, k))||(jl(i, k)==jl(i, j))||(jl(i, k)==jl(j, k)))cnt++;//是否“等腰”,答案增加
                }
            }
        }
    }
    cout<<cnt;//输出答案
    return 0;//THE END
}