第 11 课:多分支结构
氪町博士觉得蛙蛙所在的班级进行的成绩等级划分太过笼统,不利于激发学生的斗志,希望蛙蛙给班级设计出更细致的等级划分系统。现规定考试成绩对应的等级为:
分数大于或等于 90 分评 A,80(含)分至 89 分评 B,70(含)分至 79 分评 C,60(含)分至 69 分评 D,低于 60 分评 F,表示不及格。
蛙蛙瞬间想到了上节所学的选择嵌套结构,觉得可以使用该结构对 70 及 70 以上的分数进行划分,再对 70 以下的分数进行划分,于是写下:
#include <iostream>
using namespace std;
int main()
{
int score;
cin >> score; // 输入分数
if (score >= 70) // 分数大于或等于 70
{
if(score >= 90) // 分数大于或等于 90
{
cout << "等级为:A"; // 条件成立输出
}
else // 分数小于 90,但是大于或等于 70
{
if(score >= 80) // 分数大于或等于 80,但是小于 90
{
cout << "等级为:B"; // 条件成立输出
}
else // 分数小于 80,但是大于 70
{
cout << "等级为:C"; // 条件成立输出
}
}
}
else // 分数小于 70
{
if (score >= 60) // 分数大于或等于 60,小于 70
{
cout << "等级为:D"; // 条件成立输出
}
else // 分数小于 60
{
cout << "等级为:F"; // 条件成立输出
}
}
return 0;
}写完后蛙蛙编译运行,完全正确!
但氪町博士看了一眼后,觉得写得十分冗杂,决定教蛙蛙通过多分支结构进行改善。
11.1 多分支结构的基本框架
if(条件 1)
语句 1; // 满足条件 1,就执行语句 1
else if(条件 2)
语句 2; // 不满足条件 1 但是满足条件 2,执行语句 2
else if(条件 3)
语句 3; // 不满足条件 1 和条件 2,但满足条件 3,执行语句 3
……
else
语句 n; // 不满足上面所有条件,执行语句 n首行代码为 if 语句,中间都是 else if 语句,最后以 else 结尾,对应不满足上面所有条件的情况。
学会了多分支结构的基本框架后,蛙蛙开始对成绩等级划分的程序进行重构:
#include <iostream>
using namespace std;
int main()
{
int score;
cin >> score;
if (score >= 90) cout << "等级为:A";
else if (score >= 80) cout << "等级为:B";
else if (score >= 70) cout << "等级为:C";
else if (score >= 60) cout << "等级为:D";
else cout << "等级为:F";
return 0;
}编译运行没问题后,蛙蛙长舒了一口气,感叹道:这样写,看起来简洁多了!
蛙蛙又对比了这两个程序,最后总结出,if ... else 语句可以与 if ... else 的嵌套结构相互转化,但对于不同的题目来说,使用合适的结构写起来可能更加简便。
氪町博士提醒蛙蛙,在刚学习分支结构的时候,可以多运用不同的框架来解题,这样在遇到新题目的时候,才能瞬间判断出使用哪个框架更合适。
11.2 实例讲解
例 1:游玩
蛙蛙准备周末去外面游玩,但不确定周末天气如何,于是做了以下决定:如果周末是晴天(用大写 S 表示),就去爬山(用 1 表示);如果周末是阴天(用大写 O 表示),就去游乐场(用 2 表示);如果周末下雨(用大写 R 表示),就不能出门了(用 3 表示)。
【输入格式】输入一行,为一个字母,用来表示周末的天气情况。
【输出格式】输出一行,1 或者 2 或者 3,表示去哪儿玩。
【输入样例】S
【输出样例】1
解析
去游玩:如果周末是晴天,去爬山;如果周末是阴天,去游乐场。
不能出门:这里假设天气一共有三种情况,前面两种(晴天和阴天)已经分别安排了活动,因此剩下的就是第三种情况了。我们可以直接使用 else 来表示"除以上两种情况之外",即不能出门的情况。
参考代码
#include <iostream>
using namespace std;
int main()
{
char a;
cin >> a;
if (a == 'S') cout << 1;
else if (a == 'O') cout << 2;
else cout << 3;
return 0;
}例 2:群雄争霸
战国时期,各国之间纷争不断,最终还是战力强大的国家吞并了战力弱小的国家。
现在甲国的战力为 a,乙国的战力为 b,初始的战力都在 0 和 100 之间。如果甲国战力大于乙国战力,则甲国吞并乙国(a = a + b),乙国灭亡(b = 0),反之亦然。
如果战力相等,则势均力敌,两国都会存在(a 和 b 保持不变)。
两国比较后最终的战力 a 和 b 各是多少?
【输入格式】输入一行,两个正整数 a 和 b,分别表示两个国家的战力。
【输出格式】输出一行,为经过对比以后 a 和 b 的值。
【输入样例】15 20
【输出样例】0 35
解析
战力不相等:如果甲国战力 > 乙国战力,则甲国战力为甲乙两国之和,乙国战力为 0;反之亦然。
战力相等:除去上面两种情况以外的情况,则为战力相等的情况,战力相等的话两国保持不变,即保持原来的值进行输出。
参考代码
#include <iostream>
using namespace std;
int main()
{
int a, b;
cin >> a >> b;
if (a > b) cout << a + b << " 0";
else if (a < b) cout << "0 " << a + b;
else cout << a << " " << b;
return 0;
}11.3 不同三角形判断
在之前的学习中,我们已经知道三角形的成立条件是任意两边之和大于第三边了。按照边长的不同,我们还可以将三角形分为等边三角形(三条边相等)、等腰三角形(两条边相等)和不等边三角形(三条边都不相等)。
例 3:特殊三角形
输入三角形的三条边的长度,判断它是何种类型的三角形。如果是等边三角形的话,则输出 DB;如果是等腰三角形的话,则输出 DY;如果属于不等边三角形的话,则输出 YB;如果不能构成三角形,则输出 NO。
【输入格式】输入一行,三个正整数 a、b、c,分别代表三条边的边长(其中 1 ≤ a ≤ 10,1 ≤ b ≤ 10,1 ≤ c ≤ 10)。
【输出格式】输出一行,DB 或 DY 或 YB 或 NO。
【输入样例】3 4 3
【输出样例】DY
解析
判断是不是三角形:首先要判断这三条边是否能构成三角形,即要满足任意两边之和大于第三边。
假设已经是三角形:若能构成三角形,再判断这个三角形是什么类型的三角形。如果三边全相等则为等边三角形;若三边不全相等再判断是否有两边是相等的,若有两边相等则为等腰三角形;其他情况则为不等边三角形。
参考代码
#include <iostream>
using namespace std;
int main()
{
int a, b, c;
cin >> a >> b >> c;
if (a + b <= c || a + c <= b || b + c <= a) cout << "NO";
else if (a == b && a == c) cout << "DB";
else if (a == b || a == c || b == c) cout << "DY";
else cout << "YB";
return 0;
}11.4 运算符优先级
在前面的题目中,蛙蛙用到了"与"(&&)、"或"(||)以及一些关系运算符和算术运算符。他想知道这些运算符应该先算哪个,为什么不先算 ||,再算 + 或者 <=,等等。
氪町博士告诉他,这跟运算符的优先级相关。算术运算符、关系运算符和逻辑运算符的优先级从高到低排列如表 2-1 所示。
表 2-1 运算符的优先级(从高到低)
| 类别 | 运算符 |
|---|---|
| 逻辑非 | ! |
| 算术运算符 | *、/、% |
| 算术运算符 | +、- |
| 关系运算符 | >、<、==、!=、>=、<= |
| 逻辑与 | && |
| 逻辑或 | || |
例 4:计算机故障
蛙蛙的学校组织了一次竞赛,参加这次竞赛的共有 99 位学生,考试结束后老师对编号从 1 到 99 的每一位同学按成绩标注名次,并在计算机上记录。
结果计算机出现了故障,将第 1 名到第 9 名改为 10, 20, 30, …, 90 名,将第 10, 20, 30, …, 90 名改为第 1 名到第 9 名。竞赛成绩前 50 名(包括第 50 名)的同学获得奖励,后 49 名没有奖励。
学校听说蛙蛙学会了编程,希望他能帮忙排除这一故障。现在要求输入任意一位同学在计算机故障后的名次 n,程序要判断出这位同学在计算机故障之前原本排第几名,并判断他原来是否应该获得奖励。
【输入格式】输入一行,一个整数 n,表示故障后的名次(1 ≤ n ≤ 100)。
【输出格式】输出一行,为故障前的名次以及是否获得奖励,并用空格隔开(获得奖励输出 Yes,没有获得奖励输出 No)。
【输入样例】70
【输出样例】7 Yes
解析
调整现在的第 10, 20, 30, …, 90 名:现在的第 10, 20, 30, …, 90 名其实是原来的第 1 名到第 9 名,将第 10, 20, 30, …, 90 名调整回第 1 名到第 9 名,需要将这个数除以 10,比如 20 / 10 得到的结果就是 2。
调整现在的第 1 名到第 9 名:现在的第 1 名到第 9 名其实是原来的第 10, 20, 30, …, 90 名,将第 1 名到第 9 名调整回第 10, 20, 30, …, 90 名,需要将这个数乘以 10,比如 2 乘 10 得到的结果就是 20。
其他名次:其他名次不变,比如原来的第 47 名现在还是第 47 名,会获得奖励;原来的第 56 名现在还是第 56 名,不会获得奖励。
参考代码
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
if (n % 10 == 0) n = n / 10;
else if (n < 10) n = n * 10;
if (n <= 50) cout << n << " Yes";
else cout << n << " No";
return 0;
}