蓝桥杯每日真题 - 第12天

题目:(数三角)

题目描述(14届 C&C++ B组E题)

解题思路:

给定 n 个点的坐标,计算其中可以组成 等腰三角形 的三点组合数量。

  1. 核心条件:等腰三角形的定义是三角形的三条边中至少有两条边的长度相等。

  2. 坐标平面上的三点是否共线:如果三点共线,它们无法组成三角形。该程序在计算三点组合时,会排除共线的情况。

  3. 解决方案 :对于每个点 i,计算它与其他点之间的距离,并将具有相同距离的点分组,保存在一个映射表(map)中。随后从每组具有相同距离的点中,组合出两个点,构成一个等腰三角形。

代码实现(C++):

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
double dis(ll x1, ll y1, ll x2, ll y2){
    return pow((x1 - x2), 2) + pow((y1-y2),2);
}
bool check(pll p1, pll p2, pll p3){//判断是否三点共线
    if(p1.second == p2.second || p1.second == p3.second)  return p1.second == p2.second && p1.second == p3.second;
    double a = (p1.first - p2.first) * 1.0 / (p1.second-p2.second);
    double b = (p1.first - p3.first) * 1.0 / (p1.second-p3.second);
    return abs(a - b) < 1e-6;
}
int main() {
    ll n; cin >> n;
    vector<pll> arr;
    for (int i = 0; i < n; ++i) {
        ll x, y;
        cin >> x >> y;
        arr.emplace_back(x, y);
    }
    ll ans = 0;
    //equ[i]存储的是第i个点所对应的map表
    //map表的含义是 有哪些点到第i个点的距离为key,这些点的下标用一个vector收集
    vector<map<double,vector<int>>> equ(n);
    for(int i = 0; i < n; ++i){
        auto m= equ[i];
        for(int j = 0; j < n; ++j){//遍历其他的所有点,在map中记录相等距离
            if(i != j){
                pll p1 = arr[i]; pll p2 = arr[j];
                double d = dis(p1.first,p1.second,p2.first,p2.second);
                m[d].push_back(j);
            }
        }
        //收集完成之后,遍历这张map表
        for(const auto& [k,v] : m){
            for(int a = 0; a < v.size(); ++a){ //从到当前点的距离相等的点之中选取两个点a,b
                for(int b = a + 1; b < v.size(); ++b){
                    if(!check(arr[i],arr[v[a]],arr[v[b]])){//只要不是三点共线
                        ans++;
                    }
                }
            }
        }
    }
    cout << ans;
}

得到运行结果:

代码分析:

  • 距离计算dis 函数计算两个点之间的欧几里得距离的平方,这样可以避免使用浮点运算。

  • 三点共线判断check 函数通过检查斜率是否相等来判断三点是否共线。通过分段计算和比较斜率来避免浮点数精度误差。

  • 构建距离映射 :对于每个点 iii,计算它到其他点的距离,并使用 map 将这些距离相等的点分组。

  • 等腰三角形组合计数:从距离相等的点中选择两个不同的点与当前点 iii 组合成三角形,检查是否共线。若不是共线,则计数增加。

难度分析

⭐️⭐️⭐️⭐️

总结

  • 时间复杂度 :该算法的复杂度为 ,因为它使用三重循环来枚举所有三点组合。

  • 空间复杂度 :使用了 map 来存储每个点到其他点的距离信息,相应的空间复杂度为

相关推荐
好心的小明9 分钟前
【蓝桥杯】CB组国二攻略(省赛地点:广东)
职场和发展·蓝桥杯
槿花Hibiscus34 分钟前
C++基础:Pimpl设计模式的实现
c++·设计模式
用户40547878374821 小时前
深度学习笔记 - 使用YOLOv5中的c3模块进行天气识别
算法
十七算法实验室1 小时前
Matlab实现麻雀优化算法优化随机森林算法模型 (SSA-RF)(附源码)
算法·决策树·随机森林·机器学习·支持向量机·matlab·启发式算法
ღ 金龍戲水 ღ1 小时前
蓝桥杯竞赛单片机组备赛【经验帖】
经验分享·单片机·蓝桥杯
黑不拉几的小白兔1 小时前
PTA部分题目C++重练
开发语言·c++·算法
迷迭所归处1 小时前
动态规划 —— dp 问题-买卖股票的最佳时机IV
算法·动态规划
写bug的小屁孩1 小时前
websocket身份验证
开发语言·网络·c++·qt·websocket·网络协议·qt6.3
chordful2 小时前
Leetcode热题100-32 最长有效括号
c++·算法·leetcode·动态规划
_OLi_2 小时前
力扣 LeetCode 459. 重复的子字符串(Day4:字符串)
算法·leetcode·职场和发展·kmp