codeforces - 766B【三角形判断】

题解By: Jstyle
知识点一
    要想三边满足构成三角形的条件有两个
    1、任意两边之和大于第三边。
    2、任意两边之差小于第三边。
知识点二
    假设三边为 a, b, c 且满足 a <= b <= c;那么只需要满足 a+b > c即可;
    证明:
    任意两边之和大于第三边:
    因为 a <= b <= c, 则 a+c > b && b+c > a 是显然的;
    任意两边只差小于第三边:
    因为: a+b > c 所以: a > c-a && b < c-a;
    那么我们只需要证明 b-a < c即可;
    因为: b < c 所以 b-a < c-a < c即 b-a < c;
    证毕。

此题解法:
    有了以上假设解决这道题会非常容易。
    这道题有个很朴素的做法就是我们去三重for循环枚举三条边是否满足条件,但是超时也是显然的。
    基于知识点二我们可以有如下做法:
    1、将给定的n条边进行排序;
    2、从大到小去判断相邻的三条边是否有 a[i] < a[i-1]+a[i-2]的关系;
    3、如果有就直接跳出循环并输出"YES";否则继续去执行2;
    这样我们只需要 (排序+一层循环遍历) 就可以解决了,时间复杂度 O(n*logn);
    
解法的合理性:
    我们来证明一下这样的可行性:
    1、对于从大到小遍历的 c 来言,要想找到两个数 a+b > c,肯定a,b越大才越有可能成立。
    2、那对于我们排序过后的数组而言,肯定是c往下相邻的两个数是最大的。即就是a[i-1],a[i-2];
    3、如果对于当前的 a[i-2]+a[i-2] <= a[i];那么a[i]这条边就可以从我们的遍历数组中去掉了,
       因为比a[i]小的最大的两条边都不满足 a+b > c了,那么更小的边更不会满足,因此我们把a[i-1]继续作为
       c这条边继续判断。
       
希望大家能从这道理得到一些思考和启发,此题代码不长,但是需要基础的思维。

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #define N 100005
 5 using namespace std;
 6
 7 int n, a[N];
 8 int main()
 9 {
10     while(scanf("%d", &n) != EOF){
11         for(int i = 1; i <= n; ++ i)    scanf("%d", &a[i]);
12
13         sort(a+1, a+n+1);
14         int ok = 0;
15         for(int i = n; i >= 3; --i){
16             int x = a[i], y = a[i-1], z = a[i-2];
17             if(y+z > x){
18                 ok = 1;
19                 break;
20             }
21         }
22         printf(ok ? "YES\n" : "NO\n");
23     }
24     return 0;
25 }

时间: 2024-10-13 03:05:23

codeforces - 766B【三角形判断】的相关文章

分支-02. 三角形判断(15)

#include<iostream>#include<iomanip>#include<math.h>using namespace std;int main(){    double a[2],b[2],c[2];    double l,m,n,p,s;    cin>>a[0]>>a[1]>>b[0]>>b[1]>>c[0]>>c[1];    l=sqrt(pow(a[0]-b[0],2)+

*分支-02. 三角形判断

此题有错误,不能正确执行.希望有人给予提点. 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 5 int main() 6 { 7 float x1,y1,x2,y2,x3,y3;//三个坐标 8 float l1,l2,l3;//三角形三边 9 float L,A;//周长,面积 10 float S;//海伦公式 11 12 scanf("%f %f %f %f %f %f&

PAT 三角形判断

1 /*给定平面上任意三个点的坐标(x1,y1).(x2,y2).(x3,y3),检验它们能否构成三角形. 2 3 输入格式: 4 5 输入在一行中顺序给出6个[-100, 100]范围内的数字,即3个点的坐标x1, y1, x2, y2, x3, y3. 6 7 输出格式: 8 9 若这3个点不能构成三角形,则在一行中输出“Impossible”:若可以,则在一行中输出该三角形的周长和面积,格式为“L = 周长, A = 面积”,输出到小数点后2位. 10 输入样例1:4 5 6 9 7 8

浙大版《C语言程序设计(第3版)》题目集 习题3-5 三角形判断 (15 分)

习题3-5 三角形判断 (15 分) 给定平面上任意三个点的坐标(x1,y1).(x2,y2).(x3,y3),检验它们能否构成三角形.1??,y?1??).(x?2??,y?2??).(x?3??,y?3??),检验它们能否构成三角形 输入格式: 输入在一行中顺序给出六个[?100,100]范围内的数字,即三个点的坐标x1.y1.x2.y2.x3.y3.(.x1,y1).(x2,y2).(x3,y3)1??.y?1??.x?2??.y?2??.x?3??.y?3??. 输出格式: 若这3个点不

作业八—三角形判断单元测试体会

  测试用例 (含有“()”号的为错误预言) 序号 测试输入(三条边:a,b,c) 测试预言 (Oracle:Illegal,Regular,Scalene,Isoceles) 4  (0.6.5)  Illegal 5  (4,2,3)  Scalence 6  (4,4,4)  Regular 7  (-2,-2,-2)  Illegal 8  (3,3,5)  Isoceles 9  (-2,-2,-2)  (Regular) 10  (3,3,6)  (Isoceles) 11  (1,

1-4-16:三角形判断

描述 给定三个正整数,分别表示三条线段的长度,判断这三条线段能否构成一个三角形. 输入输入共一行,包含三个正整数,分别表示三条线段的长度,数与数之间以一个空格分开.输出如果能构成三角形,则输出“yes” ,否则输出“no”.样例输入 3 4 5 样例输出 yes 来源 #include<stdio.h> int main() { int a,b,c; scanf("%d%d%d",&a,&b,&c); if((a+b)>c &&

【if...else】三角形判断

给定三条边的长度,判断能否组成三角形,如果可以,判断三角形的形状. 输入要求 一组数据,每行三个实数,在(0,10]之间 输出要求 根据每行的数据判断,如果不能组成三角形,则输出"Not a triangle":如果是"等腰三角形",则输出"Isosceles triangle":如果是"直角三角形",则输出"Right triangle":如果是"等腰直角三角形",则输出"I

三角形判断和计算面积(C++实现)

#include <iostream> #include <math.h> using namespace std; void main() { int    b,c,a; float s,area; cout <<"请输入三角形三条边的大小:"; cin>>a>>b>>c; if ((a+b>c)&&(a+c>b )&&(b+c>a)) { s=(a+b+c)/2

Codeforces 1161B(判断旋转对称)

要点 外层暴力枚举转的"角度",会发现肯定是n的约数 对于m条线段想判定当前的"角度"是否ok,每个线段只要管它自己的下一个即可,不必画个圈遍历一遍 之后将本来的线段集合和当前需要的线段集合比较,如果相同则该图形旋转对称 一个小优化是只需要枚举n的质约数,质约数d含义为把圆划分成d份.这样划分成6份根本不必要枚举,如果6份行的话,2份的时候就跑出去了:如果6份不行的话--所以就不用枚举它呀- const int maxn = 1e5 + 5; int n, m; v