资讯动态

OJ刷题卡壳?XTU 1055教你用if-else多分支处理三角形类型判断

发布时间:2026/10/15 6:09:14 来源:尧图企业网站定制
刷 OJ 刷到怀疑人生的时候往往不是卡在算法上而是卡在最基础的语法和分支逻辑上。XTU OJ 的 1055 题题目名字叫“B if4”光看名字就知道这是条件判断专题里的练习题而且是 if 系列的第四题。这类题在 OJ 题库里属于“看起来简单但提交一堆红”的典型专门用来训练你对 if-else 多分支结构、边界条件、输出格式的敏感度。这篇文章就把这道题从读题到 AC 的完整链路拆开讲包括题目到底在考什么、if 语句的底层逻辑、常见坑点以及我自己调试时总结的排查套路。不管是刚开始学 C 语言的新手还是准备打基础比赛的初学者都能从这里拿到一套可以直接抄作业的思路。1. 题目拆解与考察要点1.1 这道题到底在考什么拿到“B if4”这个题号先别急着写代码。OJ 题目的命名习惯很有意思B一般表示题目在某个专题里的编号而if4直接说明了这是条件判断专题的第四题。这种命名方式在很多学校的 OJ 平台上都能看到它的潜台词是前面三道题已经让你练了简单的单分支和双分支这一题要开始上强度了考的是多分支嵌套和逻辑完整性。这类题目的核心考点通常集中在三个方面。第一你能不能把文字描述转化成清晰的分支条件而不是想到哪写到哪第二你知不知道多个条件之间的优先级关系比如先判断什么、后判断什么第三你能不能处理好边界情况比如输入的数字恰好相等、恰好为零、恰好超出某个范围。以我刷题的经验来看很多人栽在第二点和第三点上不是因为不会写 if而是因为条件的顺序排错了导致有些数据走了错误的分支。具体到 1055 题它最经典的出题方式是输入三个整数判断这三个数能不能构成三角形如果能构成再进一步判断是等边三角形、等腰三角形还是一般三角形。这个题面看起来特别朴素但它把所有 if 语句的核心考点全都装进去了多条件组合、嵌套分支、输出格式、逻辑去重。你可能会觉得这有什么难的但真到了 OJ 上错误率出奇地高。1.2 题目背后的真实意图如果你只是把这三个数输入进去然后写一堆 if 去比较相等那你大概率会掉进陷阱。这道题表面上是考三角形实际上是在考你对“分支的顺序”和“条件的互斥性”的理解是否到位。先说分支顺序。判断三角形类型的正确逻辑应该是先判断能不能构成三角形再判断是什么类型的三角形。这个顺序反过来的话题目就变味了。比如输入1 1 3它根本构不成三角形但如果你的代码先去判断等腰那就会输出“isosceles”这显然是错的。正确做法是先用“两边之和大于第三边”这个条件做一次总闸把不合法的数据全部拦下来再进入类型判断。这就是所谓的“先合法后分类”思路在很多实际开发场景里也适用。再说条件的互斥性。等边三角形是等腰三角形的特殊情况所以你在写分支的时候必须先判断等边再判断等腰。如果顺序反了等边三角形会先落入等腰的分支里输出的结果类型就是错的。这个细节特别能拉开差距因为很多自以为学会 if 的人到这里才发现自己从来没认真想过分支的先后顺序会直接影响输出结果。2. if 语句核心知识与常见误区2.1 从单分支到多分支的逻辑演进很多初学者对 if 的理解停留在“如果怎么样就怎么样”这个层面但实际写代码的时候你会发现现实问题很少是单一条件的。就拿三角形判断来说你要处理“能不能构成”和“是什么类型”两个层面的问题这就逼着你把 if 从单层扩展到多层。单分支if结构是最简单的条件成立执行代码块条件不成立跳过。双分支if-else加了一条 else 兜底条件不成立时走另一条路。而多分支就需要用到else if它本质上是在不断“排除”前面的情况。这个过程很像我们平时做选择题排除法每写一个else if你就把已经覆盖的区间从后续判断里剔除掉了。写多分支结构最重要的一个习惯是要想清楚每个条件之间的重叠关系。使用多个独立的if会导致一个问题——当输入数据满足多个条件时代码会执行多个分支输出污染。而使用else if链只要某个条件命中后面的分支就不会再被检查天然保证互斥。我在实际教学和刷题过程中见过太多次这种错误四个独立 if 分别判断四个类型结果一个输入触发了两个输出OJ 直接给你判个 Presentation Error。2.2 关系表达式与运算符优先级判断三角形类型离不开关系运算符比如a b c、a b。新手最容易在这些表达式上出岔子因为 C 语言的运算符优先级实在不算友好。先说一个经典问题a b c这种写法。在数学里这是“a 小于 b 且 b 小于 c”的意思但在 C 语言里它的计算规则完全不一样。C 语言里是左结合的a b c会先计算a b得到一个布尔值0 或 1然后再拿这个 0 或 1 去和c比较。这跟你的本意差了十万八千里。正确写法永远是用逻辑运算符连接两个独立的关系表达式a b b c。再说赋值与等值比较的坑。if (a b)在 C 语言里是合法的但它的意思是把b的值赋给a然后判断赋值后的a是否为真而不是判断a和b是否相等。写过一次这种代码排查半小时都不一定找到问题。笔者的习惯是写相等判断时把常量放左边写成if (3 a)这样万一漏写了一个等号变成if (3 a)编译器会直接报错而不是给你一个隐藏的运行时 bug。这个方法虽然是 C 语言老传统但在 OJ 刷题时守能有效拦截低级失误。逻辑运算符的短路特性也很重要。和||都具有短路性左边为假右边不再计算||左边为真右边不再计算。这个特性在常规判断里不会引发问题但如果你在条件里写了自增运算或者函数调用就要格外小心右侧代码到底有没有被执行。刷 OJ 时尽量不要做这种把戏老老实实分开写不然 debug 到崩溃。2.3 等于判断与浮点比较的坑如果用整数做三角形判断是没问题的。但一旦涉及浮点数直接就是灾难。比如你判断a b c时如果用float或double存储数据浮点精度误差可能导致本应成立的不等式在计算机中被判断为不成立或者反过来。真题里如果出现浮点输入通常需要引入一个极小值做容差比较也就是判断两个浮点数之差的绝对值是否小于某个阈值。但 1055 这类基础题输入一般给的是整数所以这里只需要记住一个原则能用整数就用整数能不开double就不开避免给自己埋雷。我见过有人把整数边长存成double然后用sqrt算面积结果边界数据全都因为浮点误差而不稳定。还有一点容易被忽略有些 OJ 题目的输入数据范围并没有明确说明。如果你不先读题确认数据类型想当然地用int去读一个超出范围的大整数结果就是直接爆掉。做题的正确姿势是读完题面后立刻确定变量类型别让类型选择成为你 WA 的根源。3. 实操从读题到 AC 的完整过程3.1 确定输入输出格式这一步看起来废话但很多人在 OJ 上栽跟头就是栽在这里。看到题目输入描述里写着“三个整数”就默认它们在同一行。但有些题的输入是每一行一个整数共三行两种不同的输入方式对应的代码写法完全不同。不要猜直接看题目给的 Input 描述和样例输入。以三角形判断题目为例如果样例输入是3 4 5说明三个数在同一行用scanf(%d %d %d, a, b, c);或者cin a b c;一行读完即可。如果样例输入是三行每行一个数那用同样的格式化读取也能正确处理因为scanf和cin都天然跳过空白字符。这里真正容易出错的是输出格式比如题目要求每个结果占一行你漏了\n那就是 Presentation Error差一个换行判错你说冤不冤。输出内容的大小写也必须严格一致。题面写Equilateral你就不能输出equilateral写No你就不能输出NO。OJ 的判题是机器逐字符比对任何细节偏差都是 WA。所以提交之前拿样例输入跑一遍肉眼核对输出和题目给的样例输出是否完全一致这个习惯能帮你省掉大量无谓的提交。3.2 设计分支结构先画逻辑再写代码拿到题先别急着上手敲拿草稿纸画一下逻辑流程。画得越清楚后面写代码越省事。以三角形判断为例整体流程是这样读入三个整数先判断排序后的三条边是否满足a b c a c b b c a不满足就输出“不能构成三角形”并结束如果满足了再判断三条边是否全部相等全部相等输出“等边三角形”否则继续判断是否有任意两条边相等有则输出“等腰三角形”都不满足就输出“一般三角形”。这里有个小技巧排序降难度。不管输入顺序如何先把三个数从小到大排个序让a b c这样三角形的判断条件就可以简化成唯一一个不等式a b c。因为在排序后的三边里只要较短两边的和大于最长边另外两个不等式一定成立。这能减少代码量也能避免漏掉某个组合。排序实现起来也很简单三行手写交换排序即可或者直接引入qsort/sort看题目语言和环境定。这种“先处理边界再逐层细化类型”的顺序就是多分支结构最核心的编排思路。如果你把等腰判断放在等边判断前面等边三角形就会同时满足等腰条件而走错分支所以等边必须优先于等腰。同理构成判断必须放在最前面否则非法数据会进入后面的分类逻辑。3.3 完整代码示例与解释下面用 C 语言写一版参考实现直接满足上述逻辑。#include stdio.h int main() { int a, b, c; int temp; while (scanf(%d %d %d, a, b, c) ! EOF) { // 排序使 a b c if (a b) { temp a; a b; b temp; } if (b c) { temp b; b c; c temp; } if (a b) { temp a; a b; b temp; } // 判断能否构成三角形 if (a b c) { if (a b b c) { printf(Equilateral\n); } else if (a b || a c || b c) { printf(Isosceles\n); } else { printf(Scalene\n); } } else { printf(Not a triangle\n); } } return 0; }我特意用while (scanf(...) ! EOF)包了一层因为很多 OJ 题目支持多组测试数据题目描述里往往会写“多组输入处理到文件结束”。如果你只写一次读入那么遇到多组数据就只会处理第一组提交上去直接 WA。这个细节经常出现在基础题里专门收拾那些不仔细读题、直接照抄单次输入模板的人。关于排序的三次交换很多人觉得写得重复但这样写最直白也最容易检查。第一次交换保证前两个数有序第二次交换保证后两个数有序第三次交换再校正前两个数。数学上等价于做一轮冒泡时间复杂度是常数的完全无所谓。你要追求优雅可以用一个辅助函数但 OJ 刷题讲究的是准确和效率简洁的代码更容易一眼看出问题。3.4 提交前的自测套路写完代码先别提交。我一般会在本地跑四组数据第一组是样例数据确认和题目给的输出一模一样第二组是边界数据比如1 1 1、1 2 3、0 0 0、2 2 5这些第三组是最大范围数据比如题目说输入不超过1000000000就真的测一个1000000000确认没有整数溢出第四组是多组数据混合输入确认循环和换行处理没问题。拿上面代码举例1 1 1应该输出Equilateral1 2 3不能构成三角形输出Not a triangle0 0 0也不能构成因为0 0 0是假的不会误判成等边。这几个测试案例能在十秒钟内让你发现 80% 的低级错误。还有一点值得提如果你用 C 写while (cin a b c)的写法在遇到文件结束符时能自动退出循环和 C 语言的EOF写法是等价的。Python 则可以用sys.stdin.read().split()一次性读入所有数据再处理。不同语言有各自的输入流处理惯例选自己最熟的即可但逻辑结构必须和上面一致。4. 常见问题与排查技巧实录4.1 输出格式错误最常见的隐形杀手OJ 判题系统对输出格式的敏感程度远超新手想象。多一个空格、少一个换行、大小写不对都可能导致非 Accepted 的评测结果。尤其是当题目要求输出一堆结果时行尾有没有多余空格、最后一行有没有换行都可能被严格比对。我的习惯是把代码里所有输出语句列出来逐条和题目说明比对。输出Equilateral\n和输出Equilateral \n肉眼看起来差不多但机器判定就是两种结果。写代码时尽量用常量字符串打印不要用多个拼接碎片凑输出这样能减少空格错误。如果你已经提交了但显示 Presentation Error先别怀疑算法把输出重新读三遍重点看空格、换行、大小写、冒号。90% 的 Presentation Error 都是这些细节问题不需要改逻辑。4.2 逻辑顺序错误等边与等腰的优先级之争这个坑我在前面已经反复强调过但它的出现频率实在太高单独拿出来再说一次。如果代码先判断等腰再判断等边那么5 5 5会被识别成等腰三角形。因为(a b || a c || b c)这个条件对5 5 5是成立的输出就错了。解决方案有两种。一种是把等边判断放在最前面直接用else if链让后面的等腰分支不会重复执行另一种是在等腰条件里显式排除等边情况比如写成(a b || b c) !(a b b c)但这样写既啰嗦又容易抄错。相比之下调整顺序才是更干净的做法。排查这类问题的时候建议把边界数据作为第一优先级测试。只测试常规三角形数据永远发现不了这个 bug只有等边三角形数据才能把它暴露出来。4.3 多组输入处理不当只过样例不算完很多练习题都要求处理多组输入。样例输入通常只给一组数据如果你的代码只写了单次处理样例能过但评测数据里一旦出现第二组程序要么只输出第一组的结果要么在异常输入后崩溃。用 C 语言要注意scanf的返回值。while (scanf(...) ! EOF)是标准写法但如果你写成while (scanf(...) 1)当一次读取三个数时返回值是 3条件就变成判断是否等于 1那就永远进不了循环。这个细节在不同题目里差别很大务必按照实际参数个数来写。我平时刷题还会额外测一组带空行的数据看看程序的健壮性。虽然scanf/cin能自动跳过空白字符但有些同学喜欢用getchar逐字符处理输入这时候空行就可能引发问题多测一组空行数据能提前暴露隐患。4.4 常见错误速查表下面这个表是我刷这类题时自己整理的适配三角形判断以及大多数 if 系列题目。每次 WA 之后先对照这张表做一轮检查很多时候问题出在你想不到的地方。错误类型典型表现快速排查方向输出格式错误结果正确但评测结果显示 Presentation Error检查空格、换行、大小写和标点逻辑优先级错误等边被输出为等腰确认等边判断在等腰之前构成判断缺失无法构成三角形的数据输出了类型确认最外层有构成合法性判断多组数据处理不当只输出第一组结果或读取不到后续数据确认循环读入判断 EOF 条件运算符优先级错误a b c写法导致判断失效使用/||连接比较表达式等值判断写成赋值程序行为随机或恒真检查是否写成类型使用不当超大整数溢出或浮点误差根据题面数据范围选择long long或double这张表解决的是“定位问题”的过程。你不需要一次性记住所有可能原因只需要在遇到 WA 时先做一轮快速对照把低级错误排除掉再去深挖逻辑问题。我刷了这么多年 OJ发现绝大多数 WA 都不是因为算法太难而是因为上面这些看似不起眼的小毛病。还有一个小技巧如果反复提交都 WA却找不到原因把代码晾一晾去跑两圈或者喝口水再回来看。人盯着一行代码太久了会形成“盲区”明明错误就写在眼前也看不出来。暂停一下换换思路往往一眼就发现问题了。5. 最后分享一个实测心得1055 这道题本身不难但它卡过的人数相当可观原因就是“简单”二字让人丧失了警惕心。我见过太多人拿到题目扫一眼觉得“这我也会”然后三分钟写完提交WA 了五次才回来看题目要求多组输入。越是基础题越需要耐心这是 OJ 刷题路上最宝贵的经验。我自己做题时还养成了一个习惯每次 AC 之后把代码重新读一遍看看有没有可以精简的分支、有没有冗余的判断条件。比如三角形判断里如果你已经做了排序那么a c的检查其实已经包含了另外两个相等判断因为三个数排序后首尾相等必然导致中间数也相等。这种小优化不能帮你从 WA 变 AC但能让你对代码的理解更深一层。如果你正在刷 OJ建议准备一个错题本专门记录自己踩过的输出格式坑和逻辑顺序坑。过一个月回头翻一翻你会发现很多错误模式反复出现。把这些规律总结成自己的检查清单后面刷任何题目都能少走弯路。这个题目只是 if 系列的小节点但把这道题吃透后面遇到多层嵌套的条件判断你心里就有底了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑