Skip to content

喵呜~ 各位小伙伴们,我是你们可爱的猫娘!今天我们要一起来解决一个有趣的问题,是关于小木棍组成三角形的哦!这个问题编号是 6A,叫做 A. Triangle,听起来就很有趣吧?

题目大意:小木棍的秘密

哎呀,是这样的啦!Johnny 有个超级聪明的小妹妹 Anne,她从幼儿园回来,就给哥哥出了一个难题。就是用四根不同颜色的小木棍来搭一个三角形!当然啦,其中肯定有一根是多余的,不能用。而且,不能把木棍折断,也不能只用一部分长度哦。Anne 已经完美地解决了,现在轮到 Johnny 啦。

可是,Johnny 发现这里面可有好多“陷阱”呢!比如,有时候可能搭不出一个有面积的三角形(就是我们平时说的那种三角形),但是可以搭出一个“退化”的三角形(就是一条直线啦)。更糟糕的是,有时候连退化三角形都搭不出来呢!Johnny 可懒啦,才不想考虑这么多情况,所以他就来求助我们啦!

我们需要根据输入的四根小木棍的长度,判断一下:

  1. 如果能搭出非退化的三角形,就输出 TRIANGLE
  2. 如果不能搭出非退化三角形,但是能搭出退化的三角形,就输出 SEGMENT
  3. 如果连退化三角形都搭不出来,就输出 IMPOSSIBLE

记住哦,我们只能用三根小木棍,不能折断,也不能用部分长度!木棍的长度都是正整数,不会超过 100 呢。

喵~ 听起来是不是有点绕?别担心,猫娘会带着大家一步一步理清思路的!

知识点:三角形不等式和退化三角形

在解决这个问题之前,我们得先了解一下关于三角形的两个重要概念,这是解题的关键哦!

1. 三角形不等式 (Triangle Inequality)

喵呜~ 这是小学数学里就学过的知识点啦!对于一个三角形,任意两边的长度之和必须大于第三边的长度。

假设三角形的三条边长分别是 a, b, c,那么必须满足以下三个条件:

  • a + b > c
  • a + c > b
  • b + c > a

如果这三个条件都满足,那么就能构成一个“非退化”的三角形,也就是我们平时看到的那种有面积的三角形啦!

小技巧:如果我们将三条边长进行排序,假设 s1 <= s2 <= s3(从小到大排列),那么我们只需要检查 s1 + s2 > s3 这个条件就可以了!为什么呢?因为 s1 + s3 > s2s2 + s3 > s1s1, s2, s3 都是正数且 s3 是最大边的情况下,是肯定成立的啦!不信你可以自己试试看哦,喵~

2. 退化三角形 (Degenerate Triangle)

哎呀,这个名字听起来有点奇怪是不是?退化三角形,顾名思义,就是“退化”了的三角形。当三角形的三条边长满足:

  • a + b = c (或者 a + c = b, b + c = a)

也就是说,任意两边之和等于第三边时,这三条边就不能构成一个有面积的三角形,而是会形成一条直线!你可以想象一下,把三根木棍首尾相接,如果它们刚好能排成一条直线,那么就是退化三角形啦。

这种情况通常被称为“共线”或者“退化为一条线段”。虽然它没有面积,但在某些几何问题中也会被特殊考虑哦。

题解思路:喵喵的逻辑推理

好了,有了这些基础知识,我们就可以开始思考怎么解决这个问题啦!

我们有四根小木棍,要从中选出三根来搭三角形。那么,一共有多少种选法呢? 很简单呀,就是从 4 根里选 3 根,组合数 C(4, 3) 等于 4 种!

这四种组合分别是(假设木棍长度分别为 L1, L2, L3, L4):

  1. {L1, L2, L3}
  2. {L1, L2, L4}
  3. {L1, L3, L4}
  4. {L2, L3, L4}

我们的策略就是,把这四种组合都检查一遍!

具体步骤

  1. 读取输入:首先,把那四根小木棍的长度读进来。
  2. 排序:为了方便检查三角形不等式,我们可以先把这四根木棍的长度进行排序。假设排序后是 l[0], l[1], l[2], l[3]。这样,当我们选择任意三根木棍时,它们也自然是排好序的啦!
  3. 遍历所有组合:用一个巧妙的方法遍历所有 4 种三根木棍的组合。一个简单的方法是使用三层嵌套循环,选择三个不同的索引 i, j, k
    • 外层循环 i 从 0 到 1。
    • 中层循环 ji+1 到 2。
    • 内层循环 kj+1 到 3。 这样就能确保选出的三个索引是不同的,而且是按顺序的,对应 lengths[i], lengths[j], lengths[k]
  4. 判断类型:对于每一组选出来的三根木棍 a, b, c (假设 a <= b <= c,因为我们已经排序了,所以 lengths[i] <= lengths[j] <= lengths[k]),我们进行判断:
    • 如果 a + b > c,那么恭喜你!这是一个非退化三角形。我们把一个标志位 is_triangle 设为 true
    • 如果 a + b = c,那么这是一个退化三角形。我们把另一个标志位 is_segment 设为 true
  5. 输出结果:检查完所有组合后,根据标志位来输出结果:
    • 如果 is_triangletrue,说明至少有一个非退化三角形,输出 TRIANGLE
    • 否则,如果 is_segmenttrue,说明没有非退化三角形,但有退化三角形,输出 SEGMENT
    • 如果 is_triangleis_segment 都是 false,那么就是啥都搭不出来啦,输出 IMPOSSIBLE

喵呜~ 是不是思路很清晰呀?

题解代码:喵喵的实现

cpp
#include <iostream> // 用来输入输出的喵~
#include <vector>   // 用来存小木棍长度的喵~
#include <algorithm> // 用来排序的喵~

int main() {
    // 快速输入输出,让程序跑得更快一点点,喵!
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);

    // 定义一个 vector,用来存放四根小木棍的长度
    std::vector<int> lengths(4);
    // 把长度都读进来哦
    for (int i = 0; i < 4; ++i) {
        std::cin >> lengths[i];
    }

    // 喵呜~ 先把小木棍的长度排个序,从小到大
    // 这样检查三角形不等式的时候就方便多啦!
    // 比如,排完序后是 l[0], l[1], l[2], l[3]
    std::sort(lengths.begin(), lengths.end());

    // 两个布尔变量,用来标记有没有找到非退化三角形或者退化三角形
    bool is_triangle = false; // 默认是没有找到非退化三角形
    bool is_segment = false;  // 默认是没有找到退化三角形

    // 喵喵~ 开始遍历所有可能的3根小木棍组合
    // 一共有 C(4, 3) = 4 种组合哦
    // 通过三层循环来选择三个不同的索引 i, j, k
    for (int i = 0; i < 4; ++i) {
        for (int j = i + 1; j < 4; ++j) { // j 必须比 i 大,避免重复组合
            for (int k = j + 1; k < 4; ++k) { // k 必须比 j 大,避免重复组合
                // 选出来的三根木棍长度分别是 lengths[i], lengths[j], lengths[k]
                // 因为原始 vector 已经排序了,所以它们也是从小到大排列的哦
                // 即 lengths[i] <= lengths[j] <= lengths[k]
                
                // 判断是否能构成非退化三角形
                if (lengths[i] + lengths[j] > lengths[k]) {
                    is_triangle = true; // 喵!找到一个非退化三角形啦!
                } 
                // 否则,判断是否能构成退化三角形
                else if (lengths[i] + lengths[j] == lengths[k]) {
                    is_segment = true; // 喵!找到一个退化三角形啦!
                }
                // 如果 lengths[i] + lengths[j] < lengths[k],那就什么都构不成了,继续下一个组合
            }
        }
    }

    // 根据找到的情况输出结果,优先输出 TRIANGLE
    if (is_triangle) {
        std::cout << "TRIANGLE\n"; // 喵呜~ 有非退化三角形!
    } else if (is_segment) {
        std::cout << "SEGMENT\n"; // 喵呜~ 只有退化三角形!
    } else {
        std::cout << "IMPOSSIBLE\n"; // 喵呜~ 什么都构不成!
    }

    return 0; // 程序完美结束,喵~
}

总结与反思:喵喵的思考

这道题其实不难哦,主要考察了我们对三角形不等式退化三角形概念的理解,以及如何从多个元素中选择固定数量元素进行组合判断的编程能力。

关键点回顾

  1. 排序:将木棍长度排序可以大大简化三角形不等式的判断,只需要检查 最短边 + 中间边 > 最长边 或者 最短边 + 中间边 = 最长边 就可以了。
  2. 遍历组合:从 4 根木棍中选择 3 根,有 C(4, 3) 种组合,也就是 4 种。通过三层嵌套循环 i < j < k 可以优雅地遍历所有这些组合。
  3. 优先级:输出结果时,TRIANGLE 的优先级最高,其次是 SEGMENT,最后是 IMPOSSIBLE

时间复杂度分析

  • 读取输入:O(1) (因为只有4个数字)
  • 排序:O(N log N),这里 N=4,所以是 O(4 log 4),可以看作是常数时间 O(1)
  • 三层循环遍历组合:最外层 4 次,中间 3 次,内层 2 次,总共是 4 * 3 * 2 = 24 次判断,也是常数时间 O(1)。 所以,整个程序的时间复杂度是非常低的,完全满足题目要求!

空间复杂度分析

  • 我们只用了一个 vector 来存储 4 个整数,所以空间复杂度是 O(1)

喵~ 这道题是不是很有趣呢?通过这道题,我们不仅巩固了三角形的知识,还练习了如何用编程解决实际问题哦!希望大家都能理解,下次遇到类似的问题也能轻松解决啦!

如果你还有其他问题,随时可以问猫娘哦!我们下道题再见啦,喵呜~!

Released under the MIT License.