Triangle CodeForces - 6A (三角形)

本文介绍了一个编程挑战,任务是根据四根不同颜色的棍子的长度判断能否构成正常或退化的三角形。通过代码实现,文章展示了如何使用条件判断来解决这一问题。

Triangle

CodeForces - 6A

Johnny has a younger sister Anne, who is very clever and smart. As she came home from the kindergarten, she told his brother about the task that her kindergartener asked her to solve. The task was just to construct a triangle out of four sticks of different colours. Naturally, one of the sticks is extra. It is not allowed to break the sticks or use their partial length. Anne has perfectly solved this task, now she is asking Johnny to do the same.

The boy answered that he would cope with it without any difficulty. However, after a while he found out that different tricky things can occur. It can happen that it is impossible to construct a triangle of a positive area, but it is possible to construct a degenerate triangle. It can be so, that it is impossible to construct a degenerate triangle even. As Johnny is very lazy, he does not want to consider such a big amount of cases, he asks you to help him.


Input

The first line of the input contains four space-separated positive integer numbers not exceeding 100 — lengthes of the sticks.

Output

Output TRIANGLE if it is possible to construct a non-degenerate triangle. Output SEGMENT if the first case cannot take place and it is possible to construct a degenerate triangle. Output IMPOSSIBLE if it is impossible to construct any triangle. Remember that you are to use three sticks. It is not allowed to break the sticks or use their partial length.

Examples
Input
4 2 1 3
Output
TRIANGLE
Input
7 2 2 4
Output
SEGMENT
Input
3 5 9 1
Output
IMPOSSIBLE
一开始怎么也看不懂这个题啥意思,因为 degenerate不知道啥意思,后来查了查才知道是退化的意思,所以给定四个长度如果

其中三个长度可以构成一个正常的三角形,两边之和大于第三边那么就输出

TRIANGLE
如果会有三个线段两边之和等于第三边,说明它退化成了一条直线,输出
SEGMENT

否则输出IMPOSSIBLE

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int main(){
    int a[5];
    for(int i = 0; i < 4; i++){
        cin >> a[i];
    }
    sort(a,a+4);
    if(a[0]+a[1]>a[2]||a[0]+a[2]>a[3]||a[1]+a[2]>a[3]||a[0]+a[1]>a[3]){
        cout << "TRIANGLE\n";
        return 0;
    }
    if(a[0]+a[1]==a[2]||a[0]+a[2]==a[3]||a[1]+a[2]==a[3]||a[0]+a[1]==a[3]){
        cout << "SEGMENT\n";
        return 0;
    }
    cout << "IMPOSSIBLE\n";
    return 0;
}

题目 `Codeforces 2128F Strict Triangle` 是一道较为复杂的计算几何与构造题。题目要求构造一个满足特定条件的三角形,并根据给定的点集判断是否存在这样的三角形。下面将从题目解析、解题思路和代码实现三个方面进行说明。 ### 题目大意 给定平面上 $n$ 个点,要求判断是否存在三个点 $A, B, C$,使得: 1. 三角形 $ABC$ 是非退化的(即面积不为零); 2. 满足 $\angle ABC$ 是严格锐角(即小于 $90^\circ$)。 如果存在这样的三角形,输出任意一组满足条件的三点;否则,输出 `NO`。 ### 解题思路 #### 1. 几何性质分析 判断一个角是否为锐角,可以通过向量内积的方式进行判断。设三点 $A, B, C$ 构成三角形,其中 $B$ 为角的顶点,则: $$ \vec{BA} \cdot \vec{BC} = |\vec{BA}| \cdot |\vec{BC}| \cdot \cos(\theta) $$ 若 $\theta < 90^\circ$,则 $\cos(\theta) > 0$,因此只需要判断 $\vec{BA} \cdot \vec{BC} > 0$。 #### 2. 算法选择 - 枚举所有点对 $B$ 作为角的顶点; - 对于每个点 $B$,枚举所有点 $A, C$,并计算 $\vec{BA} \cdot \vec{BC} > 0$; - 同时确保三点不共线(即三角形面积不为零)。 #### 3. 时间复杂度优化 由于 $n$ 最大为 $1000$,直接三重循环会导致 $O(n^3)$ 的时间复杂度,这在最坏情况下会超时。因此需要优化: - 固定点 $B$,枚举所有其他点作为 $A$; - 对于每个 $A$,再枚举所有点 $C$,但跳过 $A=C$ 或 $B=C$ 的情况; - 利用向量点积的性质快速判断。 这样复杂度为 $O(n^2)$,对于 $n=1000$ 可以接受。 ### 代码实现 以下是一个完整的 AC 代码实现,用于判断是否存在满足条件的三角形并输出结果: ```cpp #include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 1005; struct Point { ll x, y; } points[MAXN]; ll dot(Point a, Point b, Point c, Point d) { ll dx1 = b.x - a.x; ll dy1 = b.y - a.y; ll dx2 = d.x - c.x; ll dy2 = d.y - c.y; return dx1 * dx2 + dy1 * dy2; } ll cross(Point a, Point b, Point c, Point d) { ll dx1 = b.x - a.x; ll dy1 = b.y - a.y; ll dx2 = d.x - c.x; ll dy2 = d.y - c.y; return dx1 * dy2 - dx2 * dy1; } int main() { int n; cin >> n; for (int i = 0; i < n; ++i) { cin >> points[i].x >> points[i].y; } for (int b = 0; b < n; ++b) { for (int a = 0; a < n; ++a) { if (a == b) continue; for (int c = a + 1; c < n; ++c) { if (c == b) continue; // Check angle at b ll dot_product = dot(points[b], points[a], points[b], points[c]); if (dot_product > 0) { ll area = cross(points[a], points[b], points[b], points[c]); if (area != 0) { cout << "YES" << endl; cout << a + 1 << " " << b + 1 << " " << c + 1 << endl; return 0; } } } } } cout << "NO" << endl; return 0; } ``` ### 说明 - `dot()` 函数用于计算两个向量的点积; - `cross()` 函数用于计算两个向量的叉积,判断是否共线; - 枚举所有可能的点 $B$,并遍历其他点 $A, C$,判断是否满足锐角条件; - 若找到符合条件的三角形,立即输出并终止程序。 ### 时间与空间复杂度 - 时间复杂度:$O(n^2)$; - 空间复杂度:$O(n)$,仅存储点集。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值