题解:P9423 [蓝桥杯 2023 国 B] 数三角
are_you_sure · · 题解
P9423:数三角 题解
分析
这题其实并不难,直接枚举选取的三个点,求它们间的距离,判断是否组成等腰三角形,如果是答案就加
要点 1:两点之间距离公式
设第一个点为
写成代码如下:
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
}