调整课次结构:前9节重新排序,新建第06课一维数组,后3节不变
This commit is contained in:
681
第01课-数据类型与分支结构/分支结构-编程题-教师版.md
Normal file
681
第01课-数据类型与分支结构/分支结构-编程题-教师版.md
Normal file
@@ -0,0 +1,681 @@
|
||||
# 第4课编程题(教师版)
|
||||
|
||||
## 本课知识点覆盖表
|
||||
|
||||
| 核心知识点 | GESP等级 | 对应课堂题 |
|
||||
|---|---|---|
|
||||
| `if / else if / else` 多层互斥分支 | 一级必考 | 课堂1 |
|
||||
| 嵌套 `if`、逻辑运算与条件分组 | 一级必考 | 课堂2 |
|
||||
| 普通打擂台、合法初始擂主 | 一级/二级 | 课堂3 |
|
||||
| 二次打擂台、主条件与并列规则 | 二级 | 课堂4 |
|
||||
|
||||
> 本课重点训练多层分支结构。14 题中有 10 题需要三层以上分支或嵌套判断。
|
||||
|
||||
## 一、课堂练习(4题)
|
||||
|
||||
### 课堂1:阶梯电费【适中】
|
||||
|
||||
**题目描述:** 某月用电量不超过 180 度的部分每度 0.50 元;181~280 度的部分每度 0.60 元;超过 280 度的部分每度 0.80 元。若总电费超过 200 元再加收 5% 服务费。输出应付金额。
|
||||
|
||||
**输入格式:** 输入一个非负整数,表示本月用电量。
|
||||
|
||||
**输出格式:** 应付金额,保留两位小数。
|
||||
|
||||
**数据范围:** `0≤n≤10000`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
300
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
166.00
|
||||
```
|
||||
|
||||
**解题思路:** 用多层 `if-else if-else` 分段累计;计算完成后再独立判断是否加收服务费。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int n;
|
||||
cin >> n;
|
||||
double cost;
|
||||
if (n <= 180) {
|
||||
cost = n * 0.50;
|
||||
} else if (n <= 280) {
|
||||
cost = 180 * 0.50 + (n - 180) * 0.60;
|
||||
} else {
|
||||
cost = 180 * 0.50 + 100 * 0.60 + (n - 280) * 0.80;
|
||||
}
|
||||
if (cost > 200) cost *= 1.05;
|
||||
cout << fixed << setprecision(2) << cost;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 阶梯收费是分段累计,不是把全部用电量直接乘最高档单价。
|
||||
|
||||
### 课堂2:游乐园购票方案【适中】
|
||||
|
||||
**题目描述:** 输入年龄、身高和是否有成人陪同。身高低于 120 厘米免费;否则年龄不满 12 岁时,有成人陪同票价 30 元,无陪同不得入园;12~59 岁票价 80 元;60 岁及以上票价 40 元。周末所有非免费票加收 10 元。
|
||||
|
||||
**输入格式:** 依次输入年龄、身高、是否有成人陪同和是否为周末;后两项用 0 或 1 表示。
|
||||
|
||||
**输出格式:** 免费输出 `FREE`,不得入园输出 `DENIED`,否则输出票价。
|
||||
|
||||
**数据范围:** `1≤age≤120`,`50≤height≤220`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
10 135 1 1
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
40
|
||||
```
|
||||
|
||||
**解题思路:** 先判断身高;不免费时再按年龄嵌套判断,儿童分支中继续判断陪同;最后对合法票价判断周末加价。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int age, height, accompanied, weekend;
|
||||
cin >> age >> height >> accompanied >> weekend;
|
||||
if (height < 120) {
|
||||
cout << "FREE";
|
||||
} else {
|
||||
int price;
|
||||
if (age < 12) {
|
||||
if (accompanied == 0) {
|
||||
cout << "DENIED";
|
||||
return 0;
|
||||
}
|
||||
price = 30;
|
||||
} else if (age < 60) {
|
||||
price = 80;
|
||||
} else {
|
||||
price = 40;
|
||||
}
|
||||
if (weekend == 1) price += 10;
|
||||
cout << price;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** “不得入园”不是票价 0;输出后应立即结束,避免继续加价。
|
||||
|
||||
### 课堂3:最佳选手【适中】
|
||||
|
||||
**题目描述:** 输入 `n` 名选手的分数,输出最高分和第一次取得该分数的选手编号。
|
||||
|
||||
**输入格式:** 第一行输入选手人数;第二行输入每名选手的分数。
|
||||
|
||||
**输出格式:** 最高分和选手编号(从 1 开始)。
|
||||
|
||||
**数据范围:** `1≤n≤100`,分数为 `0~100`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
5
|
||||
88 95 90 95 70
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
95 2
|
||||
```
|
||||
|
||||
**解题思路:** 用第一名选手初始化擂主;只有出现严格更高分时才更新,便可保留最早编号。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int n, score, bestScore, bestId = 1;
|
||||
cin >> n >> bestScore;
|
||||
for (int id = 2; id <= n; id++) {
|
||||
cin >> score;
|
||||
if (score > bestScore) {
|
||||
bestScore = score;
|
||||
bestId = id;
|
||||
}
|
||||
}
|
||||
cout << bestScore << " " << bestId;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 擂主必须用第一个合法数据初始化;相等时不更新才能保留第一次出现的位置。
|
||||
|
||||
### 课堂4:最接近目标的候选人【适中】
|
||||
|
||||
**题目描述:** 输入目标分 `target` 以及 `n` 名候选人的编号和分数。选择与目标分距离最小者;距离相同时选分数较高者;仍相同则选编号较小者。
|
||||
|
||||
**输入格式:** 第一行输入候选人数和目标分;随后每行输入一名候选人的编号和分数。
|
||||
|
||||
**输出格式:** 入选者编号和分数。
|
||||
|
||||
**数据范围:** `1≤n≤100`,编号互不相同,分数为 `0~100`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
4 80
|
||||
3 76
|
||||
8 84
|
||||
2 84
|
||||
5 90
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
2 84
|
||||
```
|
||||
|
||||
**解题思路:** 依次比较距离、分数、编号,三层优先级构成完整更新条件。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int n, target, id, score, bestId, bestScore;
|
||||
cin >> n >> target;
|
||||
cin >> bestId >> bestScore;
|
||||
for (int i = 1; i < n; i++) {
|
||||
cin >> id >> score;
|
||||
int d = abs(score - target);
|
||||
int bestD = abs(bestScore - target);
|
||||
if (d < bestD ||
|
||||
(d == bestD && score > bestScore) ||
|
||||
(d == bestD && score == bestScore && id < bestId)) {
|
||||
bestId = id;
|
||||
bestScore = score;
|
||||
}
|
||||
}
|
||||
cout << bestId << " " << bestScore;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 三层规则按先后顺序连接,每个次级规则都只能在前级相等时生效。
|
||||
|
||||
## 二、课后作业(3题)
|
||||
|
||||
### 课后1:成绩等级【简单】
|
||||
|
||||
**题目描述:** 输入成绩:90~100 为 `A`,80~89 为 `B`,70~79 为 `C`,60~69 为 `D`,0~59 为 `E`;范围外输出 `ERROR`。
|
||||
|
||||
**输入格式:** 一个整数成绩。
|
||||
|
||||
**输出格式:** 等级或 `ERROR`。
|
||||
|
||||
**数据范围:** 输入整数绝对值不超过 1000。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
86
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
B
|
||||
```
|
||||
|
||||
**解题思路:** 先排除非法范围,再从高到低使用多层 `else if`。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int score;
|
||||
cin >> score;
|
||||
if (score < 0 || score > 100) cout << "ERROR";
|
||||
else 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 << "E";
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 从高到低判断后,不需要重复写上界。
|
||||
|
||||
### 课后2:月份天数【简单】
|
||||
|
||||
**题目描述:** 输入年份和月份,输出该月天数。闰年规则:能被 400 整除,或能被 4 整除但不能被 100 整除。
|
||||
|
||||
**输入格式:** 输入年份和月份。
|
||||
|
||||
**输出格式:** 天数;月份非法输出 `ERROR`。
|
||||
|
||||
**数据范围:** `1≤year≤9999`,月份可能为任意整数。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
2024 2
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
29
|
||||
```
|
||||
|
||||
**解题思路:** 先验证月份,再判断 2 月;2 月内部嵌套判断闰年,其余月份判断 30 天或 31 天。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int year, month;
|
||||
cin >> year >> month;
|
||||
if (month < 1 || month > 12) {
|
||||
cout << "ERROR";
|
||||
} else if (month == 2) {
|
||||
bool leap = year % 400 == 0 ||
|
||||
(year % 4 == 0 && year % 100 != 0);
|
||||
cout << (leap ? 29 : 28);
|
||||
} else if (month == 4 || month == 6 ||
|
||||
month == 9 || month == 11) {
|
||||
cout << 30;
|
||||
} else {
|
||||
cout << 31;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 闰年条件中的括号不能省略概念上的分组。
|
||||
|
||||
### 课后3:简单计算器【简单】
|
||||
|
||||
**题目描述:** 输入两个整数和运算符 `+ - * / %`,输出计算结果。除数为 0 时输出 `ERROR`,未知运算符输出 `UNKNOWN`。
|
||||
|
||||
**输入格式:** 依次输入第一个整数、运算符和第二个整数。
|
||||
|
||||
**输出格式:** 计算结果或错误信息。
|
||||
|
||||
**数据范围:** 两数绝对值不超过 10000。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
17 % 5
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
2
|
||||
```
|
||||
|
||||
**解题思路:** 先按运算符多层分支;进入除法或取模分支后再嵌套判断除数。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int a, b;
|
||||
char op;
|
||||
cin >> a >> op >> b;
|
||||
if (op == '+') cout << a + b;
|
||||
else if (op == '-') cout << a - b;
|
||||
else if (op == '*') cout << a * b;
|
||||
else if (op == '/' || op == '%') {
|
||||
if (b == 0) cout << "ERROR";
|
||||
else if (op == '/') cout << a / b;
|
||||
else cout << a % b;
|
||||
} else {
|
||||
cout << "UNKNOWN";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 除法和取模都必须先检查除数是否为 0。
|
||||
|
||||
## 三、扩展练习(7题)
|
||||
|
||||
### 扩展1:体质指数评价【基础综合】
|
||||
|
||||
**题目描述:** 输入体重(千克)和身高(米),计算 BMI。低于 18.5 输出 `LOW`,18.5~23.9 输出 `NORMAL`,24~27.9 输出 `HIGH`,28 及以上输出 `VERY HIGH`。
|
||||
|
||||
**输入格式:** 输入体重和身高两个实数。
|
||||
|
||||
**输出格式:** BMI 等级。
|
||||
|
||||
**数据范围:** `20≤weight≤300`,`1≤height≤2.5`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
60 1.70
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
NORMAL
|
||||
```
|
||||
|
||||
**解题思路:** 先计算 `weight/(height*height)`,再按从小到大的边界进行多层判断。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
double weight, height;
|
||||
cin >> weight >> height;
|
||||
double bmi = weight / (height * height);
|
||||
if (bmi < 18.5) cout << "LOW";
|
||||
else if (bmi < 24) cout << "NORMAL";
|
||||
else if (bmi < 28) cout << "HIGH";
|
||||
else cout << "VERY HIGH";
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 身高要平方;连续区间判断必须保证没有空档或重叠。
|
||||
|
||||
### 扩展2:三角形分类【中等】
|
||||
|
||||
**题目描述:** 输入三条边。不能组成三角形输出 `INVALID`;否则先按边分类输出 `EQUILATERAL`、`ISOSCELES` 或 `SCALENE`,再输出是否为直角三角形 `RIGHT` 或 `NOT RIGHT`。
|
||||
|
||||
**输入格式:** 输入三个正整数,表示三条边长。
|
||||
|
||||
**输出格式:** 两行分类结果。
|
||||
|
||||
**数据范围:** 边长不超过 10000。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
3 4 5
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
SCALENE
|
||||
RIGHT
|
||||
```
|
||||
|
||||
**解题思路:** 先判断合法性;合法后分别进行边型判断和直角判断。直角判断需覆盖三条边分别为斜边的情况。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
long long a, b, c;
|
||||
cin >> a >> b >> c;
|
||||
if (a + b <= c || a + c <= b || b + c <= a) {
|
||||
cout << "INVALID";
|
||||
return 0;
|
||||
}
|
||||
if (a == b && b == c) cout << "EQUILATERAL\n";
|
||||
else if (a == b || a == c || b == c) cout << "ISOSCELES\n";
|
||||
else cout << "SCALENE\n";
|
||||
|
||||
if (a * a + b * b == c * c ||
|
||||
a * a + c * c == b * b ||
|
||||
b * b + c * c == a * a) cout << "RIGHT";
|
||||
else cout << "NOT RIGHT";
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 必须先判断能否组成三角形;平方可能较大,应使用 `long long`。
|
||||
|
||||
### 扩展3:快递计费【中等】
|
||||
|
||||
**题目描述:** 基础运费按重量计算:不超过 1 千克 8 元;1~5 千克每增加 1 千克加 3 元,不足 1 千克按 1 千克算;超过 5 千克的部分每千克加 5 元。偏远地区加 10 元,加急再加总价的 20%。
|
||||
|
||||
**输入格式:** 依次输入包裹重量、是否为偏远地区和是否加急;后两项用 0 或 1 表示。
|
||||
|
||||
**输出格式:** 运费,保留两位小数。
|
||||
|
||||
**数据范围:** `0<w≤100`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
6.2 1 1
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
48.00
|
||||
```
|
||||
|
||||
**解题思路:** 先向上取整重量并按档位计算,再依次处理偏远和加急条件。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <iomanip>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
double w;
|
||||
int remote, urgent;
|
||||
cin >> w >> remote >> urgent;
|
||||
int kg = (int)ceil(w);
|
||||
double cost;
|
||||
if (kg <= 1) cost = 8;
|
||||
else if (kg <= 5) cost = 8 + (kg - 1) * 3;
|
||||
else cost = 8 + 4 * 3 + (kg - 5) * 5;
|
||||
if (remote) cost += 10;
|
||||
if (urgent) cost *= 1.2;
|
||||
cout << fixed << setprecision(2) << cost;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 示例中 6.2 千克按 7 千克计算;加急费在偏远附加费之后计算。
|
||||
|
||||
### 扩展4:石头剪刀布裁判【中等】
|
||||
|
||||
**题目描述:** 输入两名选手的手势 `R`(石头)、`S`(剪刀)、`P`(布)。非法手势输出 `ERROR`;相同输出 `DRAW`;否则输出 `A` 或 `B`。
|
||||
|
||||
**输入格式:** 两个字符。
|
||||
|
||||
**输出格式:** 裁判结果。
|
||||
|
||||
**数据范围:** 任意可见字符。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
R S
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
A
|
||||
```
|
||||
|
||||
**解题思路:** 先检查两个手势是否合法;再判断平局;最后用三个获胜组合判断 A 是否获胜。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
char a, b;
|
||||
cin >> a >> b;
|
||||
bool validA = a == 'R' || a == 'S' || a == 'P';
|
||||
bool validB = b == 'R' || b == 'S' || b == 'P';
|
||||
if (!validA || !validB) cout << "ERROR";
|
||||
else if (a == b) cout << "DRAW";
|
||||
else if ((a == 'R' && b == 'S') ||
|
||||
(a == 'S' && b == 'P') ||
|
||||
(a == 'P' && b == 'R')) cout << "A";
|
||||
else cout << "B";
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 合法性判断必须放在胜负判断之前。
|
||||
|
||||
### 扩展5:奖学金评定【中等】
|
||||
|
||||
**题目描述:** 输入平均分、竞赛获奖次数、志愿服务时长和是否违纪。违纪直接输出 `NONE`;否则平均分≥90 且获奖≥2 为一等奖,平均分≥85 且(获奖≥1 或服务≥50)为二等奖,平均分≥80 或服务≥100 为三等奖,其余无奖。
|
||||
|
||||
**输入格式:** 依次输入平均分、获奖次数、志愿服务时长和是否违纪。
|
||||
|
||||
**输出格式:** `FIRST`、`SECOND`、`THIRD` 或 `NONE`。
|
||||
|
||||
**数据范围:** 平均分 `0~100`,其余为非负整数,违纪用 0/1 表示。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
87 0 60 0
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
SECOND
|
||||
```
|
||||
|
||||
**解题思路:** 违纪是最高优先级;未违纪时按奖项从高到低判断,括号明确“且”“或”的组合。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int average, awards, service, violation;
|
||||
cin >> average >> awards >> service >> violation;
|
||||
if (violation) cout << "NONE";
|
||||
else if (average >= 90 && awards >= 2) cout << "FIRST";
|
||||
else if (average >= 85 && (awards >= 1 || service >= 50))
|
||||
cout << "SECOND";
|
||||
else if (average >= 80 || service >= 100) cout << "THIRD";
|
||||
else cout << "NONE";
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 一定要从高等级奖项向低等级判断,否则较宽条件会抢先匹配。
|
||||
|
||||
### 扩展6:最佳商品【略难】
|
||||
|
||||
**题目描述:** 输入 `n` 件商品的编号、价格和评分。选择评分最高的商品;评分相同时价格更低者优先;仍相同则编号更小者优先。
|
||||
|
||||
**输入格式:** 第一行输入商品数量;随后每行输入一件商品的编号、价格和评分。
|
||||
|
||||
**输出格式:** 最佳商品编号。
|
||||
|
||||
**数据范围:** `1≤n≤100`,价格和评分为正整数。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
4
|
||||
5 100 9
|
||||
2 120 9
|
||||
8 80 8
|
||||
3 100 9
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
3
|
||||
```
|
||||
|
||||
**解题思路:** 第一优先级比较评分,第二优先级比较价格,第三优先级比较编号。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int n, id, price, score;
|
||||
int bestId, bestPrice, bestScore;
|
||||
cin >> n >> bestId >> bestPrice >> bestScore;
|
||||
for (int i = 1; i < n; i++) {
|
||||
cin >> id >> price >> score;
|
||||
if (score > bestScore ||
|
||||
(score == bestScore && price < bestPrice) ||
|
||||
(score == bestScore && price == bestPrice && id < bestId)) {
|
||||
bestId = id;
|
||||
bestPrice = price;
|
||||
bestScore = score;
|
||||
}
|
||||
}
|
||||
cout << bestId;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 不要用任意极值初始化三个擂台变量,直接读入第一件商品最安全。
|
||||
|
||||
### 扩展7:综合录取规则【略难】
|
||||
|
||||
**题目描述:** 输入笔试、面试、体育三项成绩,以及是否有竞赛一等奖。任一成绩不在 0~100 输出 `ERROR`。竞赛一等奖且笔试≥70 可直接录取;否则笔试≥85 时,面试≥80 且体育≥60 录取;笔试 75~84 时,面试≥90 且体育≥70 才录取;其他情况不录取。
|
||||
|
||||
**输入格式:** 依次输入笔试成绩、面试成绩、体育成绩和是否获得竞赛一等奖;最后一项用 0 或 1 表示。
|
||||
|
||||
**输出格式:** `ADMITTED`、`REJECTED` 或 `ERROR`。
|
||||
|
||||
**数据范围:** 成绩可能为任意整数。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
78 92 75 0
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
ADMITTED
|
||||
```
|
||||
|
||||
**解题思路:** 先做数据合法性检查,再判断特殊录取,最后按笔试档位嵌套判断面试和体育条件。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int written, interview, sport, prize;
|
||||
cin >> written >> interview >> sport >> prize;
|
||||
if (written < 0 || written > 100 ||
|
||||
interview < 0 || interview > 100 ||
|
||||
sport < 0 || sport > 100) {
|
||||
cout << "ERROR";
|
||||
} else if (prize == 1 && written >= 70) {
|
||||
cout << "ADMITTED";
|
||||
} else if (written >= 85) {
|
||||
if (interview >= 80 && sport >= 60) cout << "ADMITTED";
|
||||
else cout << "REJECTED";
|
||||
} else if (written >= 75) {
|
||||
if (interview >= 90 && sport >= 70) cout << "ADMITTED";
|
||||
else cout << "REJECTED";
|
||||
} else {
|
||||
cout << "REJECTED";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 数据检查、特殊规则、普通规则的优先级不能调换。
|
||||
289
第01课-数据类型与分支结构/教案-学生版.md
Normal file
289
第01课-数据类型与分支结构/教案-学生版.md
Normal file
@@ -0,0 +1,289 @@
|
||||
# 第4课:数据类型、ASCII码与分支结构
|
||||
|
||||
## 教学目标
|
||||
- 掌握五种常用数据类型:int、char、double、bool、string
|
||||
- 理解 char 的 ASCII 码本质
|
||||
- 能用 ASCII 码判断和转换字符类型
|
||||
- 掌握 double 的格式化输出
|
||||
- 掌握输入输出、运算符、类型转换和多层分支
|
||||
- 认识 switch、三目运算和打擂台
|
||||
|
||||
## 核心考点:数据类型、类型转换与数据范围
|
||||
|
||||
### 考什么
|
||||
选择正确的________,判断表达式结果,完成字符与整数转换,并识别溢出或精度问题。
|
||||
|
||||
### 必须理解
|
||||
两个整数相除会进行________除法,小数部分会________。`char` 内部保存字符对应的________码。较大整数通常使用________。
|
||||
|
||||
### 核心写法
|
||||
```cpp
|
||||
double avg = ________ * sum / n;
|
||||
int d = c - ________;
|
||||
char c = d + ________;
|
||||
long long mul = ________ * a * b;
|
||||
```
|
||||
|
||||
### 常见错误
|
||||
- 为什么 `double avg = sum / n;` 仍可能丢失小数?________
|
||||
- 字符 `'5'` 和整数 `5` 是否相同?________________
|
||||
- 怎样避免 `a * b` 在赋值前已经溢出?________________
|
||||
|
||||
### 判断是否掌握
|
||||
- [ ] 我能根据范围选择数据类型。
|
||||
- [ ] 我能判断整数除法和类型转换结果。
|
||||
- [ ] 我能转换数字字符与整数。
|
||||
|
||||
---
|
||||
|
||||
## 一级、二级核心:运算、转换与分支
|
||||
|
||||
### 类型转换
|
||||
|
||||
```cpp
|
||||
double avg = ______ * sum / cnt;
|
||||
int num = (int)ch;
|
||||
char ch = (char)num;
|
||||
```
|
||||
|
||||
整数除法会不会保留小数:______。
|
||||
|
||||
### 多层分支
|
||||
|
||||
```cpp
|
||||
if (score >= 90) {
|
||||
cout << "A";
|
||||
} else if (score >= 80) {
|
||||
cout << "B";
|
||||
} else {
|
||||
cout << "C";
|
||||
}
|
||||
```
|
||||
|
||||
### `switch` 语句
|
||||
|
||||
```cpp
|
||||
switch (op) {
|
||||
case 1: cout << "加法"; ______;
|
||||
case 2: cout << "减法"; ______;
|
||||
default: cout << "无效选择";
|
||||
}
|
||||
```
|
||||
|
||||
### 三目运算
|
||||
|
||||
```cpp
|
||||
int ma = (a > b) ? ______ : ______;
|
||||
```
|
||||
|
||||
### 二次打擂台
|
||||
|
||||
先比较 ______,相同时再比较 ______。擂主应使用第一个合法候选值初始化。
|
||||
|
||||
## 课堂编程题
|
||||
|
||||
### 数据类型部分
|
||||
|
||||
#### 课堂1:超大长方体体积【适中】
|
||||
|
||||
**题目描述:** 输入长方体的长、宽、高,输出体积。三个量都能用 `int` 保存,但乘积可能超过 `int` 范围。
|
||||
|
||||
**输入格式:** 输入三个正整数,依次表示长、宽和高。
|
||||
|
||||
**输出格式:** 长方体体积。
|
||||
|
||||
**数据范围:** `1≤a,b,c≤10^6`,答案不超过 `10^18`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
100000 100000 2
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
20000000000
|
||||
```
|
||||
|
||||
**解题思路:** 用 `1LL*a*b*c` 使第一次乘法就按 `long long` 计算。
|
||||
|
||||
**易错提醒:** 只把结果变量写成 `long long` 不够,右侧的乘法也必须提前转换。
|
||||
|
||||
#### 课堂2:比赛平均分【适中】
|
||||
|
||||
**题目描述:** 输入三名选手的总分和比赛场数,分别输出三人的平均分,保留两位小数;最后输出最高平均分。
|
||||
|
||||
**输入格式:** 依次输入三名选手的总分和比赛场数。
|
||||
|
||||
**输出格式:** 第一行三个平均分;第二行最高平均分,均保留两位小数。
|
||||
|
||||
**数据范围:** `1≤n≤100`,`0≤s1,s2,s3≤10000`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
25 20 29 3
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
8.33 6.67 9.67
|
||||
9.67
|
||||
```
|
||||
|
||||
**解题思路:** 用 `1.0*s/n` 触发浮点除法,使用 `fixed` 和 `setprecision(2)`。
|
||||
|
||||
**易错提醒:** `double a=s1/n` 仍会先做整数除法,小数已经丢失。
|
||||
|
||||
#### 课堂3:字母变身与平移【适中】
|
||||
|
||||
**题目描述:** 输入一个英文字母和整数 `k`。先把字母转换为相反大小写,再在保持新大小写的前提下向后循环平移 `k` 位。
|
||||
|
||||
**输入格式:** 输入一个英文字母和向后平移的位数。
|
||||
|
||||
**输出格式:** 转换并平移后的字母。
|
||||
|
||||
**数据范围:** `0≤k≤10^9`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
Y 3
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
b
|
||||
```
|
||||
|
||||
**解题思路:** 大小写互转可利用 ASCII 差值;平移只需使用 `k%26`,公式为 `(c-base+k)%26+base`。
|
||||
|
||||
**易错提醒:** 平移必须循环;不能直接输出 `c+k`,否则可能越过字母范围。
|
||||
|
||||
#### 课堂4:账号检查器【适中】
|
||||
|
||||
**题目描述:** 输入一个不含空格的字符串。若长度不少于 6,且同时含有大写字母、小写字母和数字,输出 `YES`,否则输出 `NO`。
|
||||
|
||||
**输入格式:** 一个字符串。
|
||||
|
||||
**输出格式:** `YES` 或 `NO`。
|
||||
|
||||
**数据范围:** 字符串长度不超过 100。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
Abc123
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
YES
|
||||
```
|
||||
|
||||
**解题思路:** 用三个 `bool` 变量记录是否出现三类字符,遍历 `string` 后综合判断。
|
||||
|
||||
**易错提醒:** `bool` 只记录真假;三个条件必须同时满足,应使用 `&&`。
|
||||
|
||||
### 分支结构部分
|
||||
|
||||
#### 课堂5:阶梯电费【适中】
|
||||
|
||||
**题目描述:** 某月用电量不超过 180 度的部分每度 0.50 元;181~280 度的部分每度 0.60 元;超过 280 度的部分每度 0.80 元。若总电费超过 200 元再加收 5% 服务费。输出应付金额。
|
||||
|
||||
**输入格式:** 输入一个非负整数,表示本月用电量。
|
||||
|
||||
**输出格式:** 应付金额,保留两位小数。
|
||||
|
||||
**数据范围:** `0≤n≤10000`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
300
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
166.00
|
||||
```
|
||||
|
||||
**解题思路:** 用多层 `if-else if-else` 分段累计;计算完成后再独立判断是否加收服务费。
|
||||
|
||||
**易错提醒:** 阶梯收费是分段累计,不是把全部用电量直接乘最高档单价。
|
||||
|
||||
#### 课堂6:游乐园购票方案【适中】
|
||||
|
||||
**题目描述:** 输入年龄、身高和是否有成人陪同。身高低于 120 厘米免费;否则年龄不满 12 岁时,有成人陪同票价 30 元,无陪同不得入园;12~59 岁票价 80 元;60 岁及以上票价 40 元。周末所有非免费票加收 10 元。
|
||||
|
||||
**输入格式:** 依次输入年龄、身高、是否有成人陪同和是否为周末;后两项用 0 或 1 表示。
|
||||
|
||||
**输出格式:** 免费输出 `FREE`,不得入园输出 `DENIED`,否则输出票价。
|
||||
|
||||
**数据范围:** `1≤age≤120`,`50≤height≤220`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
10 135 1 1
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
40
|
||||
```
|
||||
|
||||
**解题思路:** 先判断身高;不免费时再按年龄嵌套判断,儿童分支中继续判断陪同;最后对合法票价判断周末加价。
|
||||
|
||||
**易错提醒:** "不得入园"不是票价 0;输出后应立即结束,避免继续加价。
|
||||
|
||||
#### 课堂7:最佳选手【适中】
|
||||
|
||||
**题目描述:** 输入 `n` 名选手的分数,输出最高分和第一次取得该分数的选手编号。
|
||||
|
||||
**输入格式:** 第一行输入选手人数;第二行输入每名选手的分数。
|
||||
|
||||
**输出格式:** 最高分和选手编号(从 1 开始)。
|
||||
|
||||
**数据范围:** `1≤n≤100`,分数为 `0~100`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
5
|
||||
88 95 90 95 70
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
95 2
|
||||
```
|
||||
|
||||
**解题思路:** 用第一名选手初始化擂主;只有出现严格更高分时才更新,便可保留最早编号。
|
||||
|
||||
**易错提醒:** 擂主必须用第一个合法数据初始化;相等时不更新才能保留第一次出现的位置。
|
||||
|
||||
#### 课堂8:最接近目标的候选人【适中】
|
||||
|
||||
**题目描述:** 输入目标分 `target` 以及 `n` 名候选人的编号和分数。选择与目标分距离最小者;距离相同时选分数较高者;仍相同则选编号较小者。
|
||||
|
||||
**输入格式:** 第一行输入候选人数和目标分;随后每行输入一名候选人的编号和分数。
|
||||
|
||||
**输出格式:** 入选者编号和分数。
|
||||
|
||||
**数据范围:** `1≤n≤100`,编号互不相同,分数为 `0~100`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
4 80
|
||||
3 76
|
||||
8 84
|
||||
2 84
|
||||
5 90
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
2 84
|
||||
```
|
||||
|
||||
**解题思路:** 依次比较距离、分数、编号,三层优先级构成完整更新条件。
|
||||
|
||||
**易错提醒:** 三层规则按先后顺序连接,每个次级规则都只能在前级相等时生效。
|
||||
|
||||
## 课后作业
|
||||
|
||||
> 请完成本课对应的课后作业,见编程题文件。
|
||||
283
第01课-数据类型与分支结构/教案-教师版.md
Normal file
283
第01课-数据类型与分支结构/教案-教师版.md
Normal file
@@ -0,0 +1,283 @@
|
||||
# 第4课:数据类型、ASCII码与分支结构
|
||||
|
||||
## 教学目标
|
||||
- 掌握五种常用数据类型:int、char、double、bool、string
|
||||
- 理解 char 的 ASCII 码本质
|
||||
- 能用 ASCII 码判断和转换字符类型
|
||||
- 掌握 double 的格式化输出
|
||||
- 掌握输入输出、算术/关系/逻辑运算与类型转换
|
||||
- 掌握 if、else if、else、switch 和三目运算
|
||||
- 掌握普通打擂台与带并列规则的二次打擂台
|
||||
|
||||
## 核心考点:数据类型、类型转换与数据范围
|
||||
|
||||
### 考什么
|
||||
考试会要求判断变量应使用哪种类型、计算表达式结果、完成字符与整数转换,或分析整数溢出和小数精度。真正的重点是:数据以什么形式存储,会直接影响运算结果。
|
||||
|
||||
### 必须理解
|
||||
`int` 存整数,范围有限;较大的整数应使用 `long long`。`double` 存小数,但可能存在微小精度误差。`char` 表面是字符,内部保存对应的 ASCII 整数,因此 `'7' - '0'` 得到整数 7。两个整数相除仍做整数除法,小数部分会被截掉;只要一边先转成 `double`,才会保留小数。赋值或运算时发生类型转换,可能扩大范围,也可能丢失信息。
|
||||
|
||||
### 核心写法
|
||||
```cpp
|
||||
double average = 1.0 * sum / n; // 先变成浮点运算
|
||||
int digit = c - '0'; // 数字字符转整数
|
||||
char c = digit + '0'; // 0~9 转数字字符
|
||||
long long product = 1LL * a * b;
|
||||
```
|
||||
`1.0` 触发浮点运算,`1LL` 让乘法从一开始就在 `long long` 范围内进行。
|
||||
|
||||
### 常见错误
|
||||
- `double average = sum / n;` 中右边先做整数除法,赋给 double 时小数已经丢失。
|
||||
- 把字符 `'5'` 当成整数 5;它们的存储值不同。
|
||||
- 结果变量使用 `long long`,但 `a * b` 已先按 int 溢出。
|
||||
- 用 `==` 直接比较复杂浮点计算结果,忽略精度误差。
|
||||
|
||||
### 判断是否掌握
|
||||
能根据数据范围选择 `int`、`long long` 或 `double`,能手算整数除法与类型转换结果,并能完成数字字符和整数之间的转换。
|
||||
|
||||
---
|
||||
|
||||
## 一级、二级核心:运算、转换与分支
|
||||
|
||||
### 输入输出与运算符
|
||||
|
||||
一级要求熟练使用 `cin`、`cout`,掌握算术、关系和逻辑运算:
|
||||
|
||||
```cpp
|
||||
int a, b;
|
||||
cin >> a >> b;
|
||||
cout << a + b << endl;
|
||||
|
||||
bool valid = (a >= 0 && a <= 100);
|
||||
```
|
||||
|
||||
整数除法会丢弃小数部分;需要小数时,应让至少一个运算数先转成 `double`。
|
||||
|
||||
### 隐式转换与强制转换
|
||||
|
||||
```cpp
|
||||
double average = 1.0 * sum / count; // 隐式转换为 double
|
||||
int code = (int)letter; // 强制转换为 int
|
||||
char letter = (char)code; // 强制转换为 char
|
||||
```
|
||||
|
||||
类型范围变大通常较安全;从浮点数转成整数会丢弃小数部分。
|
||||
|
||||
### 多层分支
|
||||
|
||||
```cpp
|
||||
if (score >= 90) {
|
||||
cout << "A";
|
||||
} else if (score >= 80) {
|
||||
cout << "B";
|
||||
} else if (score >= 60) {
|
||||
cout << "C";
|
||||
} else {
|
||||
cout << "D";
|
||||
}
|
||||
```
|
||||
|
||||
多个条件互斥时使用 `else if`,避免多个独立 `if` 重复执行。
|
||||
|
||||
### `switch` 语句
|
||||
|
||||
```cpp
|
||||
switch (choice) {
|
||||
case 1: cout << "加法"; break;
|
||||
case 2: cout << "减法"; break;
|
||||
default: cout << "无效选择";
|
||||
}
|
||||
```
|
||||
|
||||
`switch` 适合根据一个整数或字符的不同取值进行分支。每个 `case` 后通常需要 `break`,否则会继续执行后面的分支。
|
||||
|
||||
### 三目运算
|
||||
|
||||
```cpp
|
||||
int bigger = (a > b) ? a : b;
|
||||
```
|
||||
|
||||
三目运算适合简单的二选一,不适合代替复杂的多层分支。
|
||||
|
||||
### 打擂台与二次规则
|
||||
|
||||
寻找最接近目标值的数时,先比较距离;距离相同再比较数值:
|
||||
|
||||
```cpp
|
||||
if (abs(x - target) < abs(best - target) ||
|
||||
(abs(x - target) == abs(best - target) && x < best)) {
|
||||
best = x;
|
||||
}
|
||||
```
|
||||
|
||||
擂主必须用第一个合法候选值初始化,不能随意设为 0。
|
||||
|
||||
## 题目一:判断字符类型并输出ASCII码
|
||||
|
||||
### 核心代码(一句话)
|
||||
> 字符类型判断的核心:**char 本质是整数(ASCII码),可以在字符范围和整数之间自由比较和转换。**
|
||||
|
||||
### 自然语言思路
|
||||
键盘上敲的每个字符,在计算机里都存成了一个整数——这就是 **ASCII 码**。
|
||||
|
||||
记住三个关键 ASCII 码:
|
||||
- `'0'` = 48,`'1'`~`'9'` 依次递增
|
||||
- `'A'` = 65,`'B'`~`'Z'` 依次递增
|
||||
- `'a'` = 97,`'b'`~`'z'` 依次递增
|
||||
|
||||
所以判断一个字符是什么类型,有两种方法:
|
||||
|
||||
**方法一(看 ASCII 码范围)**:
|
||||
- 如果 `c` 在 `'A'` ~ `'Z'` 之间(即 65~90)→ 大写字母
|
||||
- 如果 `c` 在 `'a'` ~ `'z'` 之间(即 97~122)→ 小写字母
|
||||
- 如果 `c` 在 `'0'` ~ `'9'` 之间(即 48~57)→ 数字
|
||||
- 否则 → 其他字符
|
||||
|
||||
**方法二(用第1课学的自带函数)**:
|
||||
- `isupper(c)` → 大写字母
|
||||
- `islower(c)` → 小写字母
|
||||
- `isdigit(c)` → 数字
|
||||
|
||||
最后,`int(c)` 或 `(int)c` 直接输出字符对应的 ASCII 码值。
|
||||
|
||||
### 伪代码
|
||||
```
|
||||
输入字符 ch
|
||||
|
||||
如果 ch 在 'A' ~ 'Z' 之间:
|
||||
输出 "大写字母"
|
||||
否则如果 ch 在 'a' ~ 'z' 之间:
|
||||
输出 "小写字母"
|
||||
否则如果 ch 在 '0' ~ '9' 之间:
|
||||
输出 "数字"
|
||||
否则:
|
||||
输出 "其他字符"
|
||||
|
||||
输出 "ASCII码 = " + int(ch)
|
||||
```
|
||||
|
||||
### 真实代码
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <cctype> // isupper、islower、isdigit
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
char ch;
|
||||
cin >> ch;
|
||||
|
||||
// 方法一:ASCII 码范围判断
|
||||
if (ch >= 'A' && ch <= 'Z') {
|
||||
cout << "大写字母" << endl;
|
||||
} else if (ch >= 'a' && ch <= 'z') {
|
||||
cout << "小写字母" << endl;
|
||||
} else if (ch >= '0' && ch <= '9') {
|
||||
cout << "数字" << endl;
|
||||
} else {
|
||||
cout << "其他字符" << endl;
|
||||
}
|
||||
|
||||
// 输出 ASCII 码值
|
||||
cout << "ASCII码 = " << (int)ch << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### 方法二(用自带函数,更简洁)
|
||||
```cpp
|
||||
if (isupper(ch)) {
|
||||
cout << "大写字母" << endl;
|
||||
} else if (islower(ch)) {
|
||||
cout << "小写字母" << endl;
|
||||
} else if (isdigit(ch)) {
|
||||
cout << "数字" << endl;
|
||||
} else {
|
||||
cout << "其他字符" << endl;
|
||||
}
|
||||
```
|
||||
|
||||
### 注意点
|
||||
1. **`char` 能直接比大小**:`ch >= 'A'` 就是在比较 ASCII 码值,不需要先转成 int。
|
||||
2. **字符写单引号**:`'A'` 不是 `"A"`,单引号是 char,双引号是字符串。
|
||||
3. **ASCII 码值记忆技巧**:`'0'`=48,`'A'`=65,`'a'`=97。小写字母 = 大写字母 + 32。
|
||||
4. **大小写互转**:大写转小写 `ch + 32`,小写转大写 `ch - 32`。或者用 `tolower(ch)` / `toupper(ch)`(返回 int,需要转回 char)。
|
||||
5. **不要混用 string 和 char**:`string` 是字符串(双引号),`char` 是单个字符(单引号),两者不同。
|
||||
|
||||
---
|
||||
|
||||
## 题目二:(待橙子补充)
|
||||
|
||||
> 建议覆盖:double 格式化输出、int vs long long 范围等
|
||||
|
||||
---
|
||||
|
||||
### 核心代码(一句话)
|
||||
>
|
||||
|
||||
### 自然语言思路
|
||||
|
||||
|
||||
### 伪代码
|
||||
|
||||
|
||||
### 真实代码
|
||||
```cpp
|
||||
|
||||
```
|
||||
|
||||
### 注意点
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 题目三:(待橙子补充)
|
||||
|
||||
> 建议覆盖:bool 类型、string 基本操作等
|
||||
|
||||
---
|
||||
|
||||
### 核心代码(一句话)
|
||||
>
|
||||
|
||||
### 自然语言思路
|
||||
|
||||
|
||||
### 伪代码
|
||||
|
||||
|
||||
### 真实代码
|
||||
```cpp
|
||||
|
||||
```
|
||||
|
||||
### 注意点
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 本课打油诗
|
||||
|
||||
> int 存整数范围广,char 单字符本质藏。
|
||||
> double 小数保精度,bool 对错分两旁。
|
||||
> string 处理字符串,五种类型记心上。
|
||||
|
||||
---
|
||||
|
||||
## ASCII 码速查表(常用)
|
||||
|
||||
| 字符 | ASCII 码 |
|
||||
|------|----------|
|
||||
| `'0'` ~ `'9'` | 48 ~ 57 |
|
||||
| `'A'` ~ `'Z'` | 65 ~ 90 |
|
||||
| `'a'` ~ `'z'` | 97 ~ 122 |
|
||||
| 空格 `' '` | 32 |
|
||||
|
||||
> 记忆口诀:**4A = 65**,不是"4个A",是"数字4开头,A是65"。小写比大写多32。
|
||||
|
||||
---
|
||||
|
||||
## 课后作业
|
||||
(待补充)
|
||||
1.
|
||||
2.
|
||||
581
第01课-数据类型与分支结构/数据类型-编程题-教师版.md
Normal file
581
第01课-数据类型与分支结构/数据类型-编程题-教师版.md
Normal file
@@ -0,0 +1,581 @@
|
||||
# 第3课编程题(教师版)
|
||||
|
||||
## 本课知识点覆盖表
|
||||
|
||||
| 核心知识点 | GESP等级 | 对应课堂题 |
|
||||
|---|---|---|
|
||||
| `int`、`long long`、数据范围与 `1LL` | 一级必考 | 课堂1 |
|
||||
| `double`、整数除法、类型转换、格式化输出 | 一级必考 | 课堂2 |
|
||||
| `char`、ASCII 码、大小写转换、字母平移 | 一级/二级必考 | 课堂3 |
|
||||
| `bool`、`string`、字符与数字转换 | 一级/二级 | 课堂4 |
|
||||
|
||||
> 本课加强大小写转换和字母平移训练。字母平移均按英文字母表循环,即 `Z` 的下一个字母是 `A`。
|
||||
|
||||
## 一、课堂练习(4题)
|
||||
|
||||
### 课堂1:超大长方体体积【适中】
|
||||
|
||||
**题目描述:** 输入长方体的长、宽、高,输出体积。三个量都能用 `int` 保存,但乘积可能超过 `int` 范围。
|
||||
|
||||
**输入格式:** 输入三个正整数,依次表示长、宽和高。
|
||||
|
||||
**输出格式:** 长方体体积。
|
||||
|
||||
**数据范围:** `1≤a,b,c≤10^6`,答案不超过 `10^18`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
100000 100000 2
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
20000000000
|
||||
```
|
||||
|
||||
**解题思路:** 用 `1LL*a*b*c` 使第一次乘法就按 `long long` 计算。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int a, b, c;
|
||||
cin >> a >> b >> c;
|
||||
long long volume = 1LL * a * b * c;
|
||||
cout << volume;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 只把结果变量写成 `long long` 不够,右侧的乘法也必须提前转换。
|
||||
|
||||
### 课堂2:比赛平均分【适中】
|
||||
|
||||
**题目描述:** 输入三名选手的总分和比赛场数,分别输出三人的平均分,保留两位小数;最后输出最高平均分。
|
||||
|
||||
**输入格式:** 依次输入三名选手的总分和比赛场数。
|
||||
|
||||
**输出格式:** 第一行三个平均分;第二行最高平均分,均保留两位小数。
|
||||
|
||||
**数据范围:** `1≤n≤100`,`0≤s1,s2,s3≤10000`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
25 20 29 3
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
8.33 6.67 9.67
|
||||
9.67
|
||||
```
|
||||
|
||||
**解题思路:** 用 `1.0*s/n` 触发浮点除法,使用 `fixed` 和 `setprecision(2)`。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int s1, s2, s3, n;
|
||||
cin >> s1 >> s2 >> s3 >> n;
|
||||
double a = 1.0 * s1 / n;
|
||||
double b = 1.0 * s2 / n;
|
||||
double c = 1.0 * s3 / n;
|
||||
cout << fixed << setprecision(2);
|
||||
cout << a << " " << b << " " << c << "\n";
|
||||
cout << max(a, max(b, c));
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** `double a=s1/n` 仍会先做整数除法,小数已经丢失。
|
||||
|
||||
### 课堂3:字母变身与平移【适中】
|
||||
|
||||
**题目描述:** 输入一个英文字母和整数 `k`。先把字母转换为相反大小写,再在保持新大小写的前提下向后循环平移 `k` 位。
|
||||
|
||||
**输入格式:** 输入一个英文字母和向后平移的位数。
|
||||
|
||||
**输出格式:** 转换并平移后的字母。
|
||||
|
||||
**数据范围:** `0≤k≤10^9`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
Y 3
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
b
|
||||
```
|
||||
|
||||
**解题思路:** 大小写互转可利用 ASCII 差值;平移只需使用 `k%26`,公式为 `(c-base+k)%26+base`。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
char c;
|
||||
long long k;
|
||||
cin >> c >> k;
|
||||
if (c >= 'A' && c <= 'Z') c = c + ('a' - 'A');
|
||||
else c = c - ('a' - 'A');
|
||||
char base = (c >= 'a' && c <= 'z') ? 'a' : 'A';
|
||||
c = (c - base + k % 26) % 26 + base;
|
||||
cout << c;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 平移必须循环;不能直接输出 `c+k`,否则可能越过字母范围。
|
||||
|
||||
### 课堂4:账号检查器【适中】
|
||||
|
||||
**题目描述:** 输入一个不含空格的字符串。若长度不少于 6,且同时含有大写字母、小写字母和数字,输出 `YES`,否则输出 `NO`。
|
||||
|
||||
**输入格式:** 一个字符串。
|
||||
|
||||
**输出格式:** `YES` 或 `NO`。
|
||||
|
||||
**数据范围:** 字符串长度不超过 100。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
Abc123
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
YES
|
||||
```
|
||||
|
||||
**解题思路:** 用三个 `bool` 变量记录是否出现三类字符,遍历 `string` 后综合判断。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
string s;
|
||||
cin >> s;
|
||||
bool upper = false, lower = false, digit = false;
|
||||
for (char c : s) {
|
||||
if (c >= 'A' && c <= 'Z') upper = true;
|
||||
else if (c >= 'a' && c <= 'z') lower = true;
|
||||
else if (c >= '0' && c <= '9') digit = true;
|
||||
}
|
||||
bool valid = s.size() >= 6 && upper && lower && digit;
|
||||
cout << (valid ? "YES" : "NO");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** `bool` 只记录真假;三个条件必须同时满足,应使用 `&&`。
|
||||
|
||||
## 二、课后作业(3题)
|
||||
|
||||
### 课后1:小写转大写【简单】
|
||||
|
||||
**题目描述:** 输入一个小写字母,使用 ASCII 码运算转成大写字母。
|
||||
|
||||
**输入格式:** 一个小写字母。
|
||||
|
||||
**输出格式:** 对应的大写字母。
|
||||
|
||||
**数据范围:** `a~z`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
g
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
G
|
||||
```
|
||||
|
||||
**解题思路:** 小写字母比对应大写字母的 ASCII 码大 32,计算 `c-'a'+'A'`。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
char c;
|
||||
cin >> c;
|
||||
cout << (char)(c - 'a' + 'A');
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 字符常量必须使用单引号。
|
||||
|
||||
### 课后2:数字字符还原【简单】
|
||||
|
||||
**题目描述:** 输入一个数字字符,输出它代表的整数再加 5 的结果。
|
||||
|
||||
**输入格式:** 输入一个范围为 0~9 的数字字符。
|
||||
|
||||
**输出格式:** 一个整数。
|
||||
|
||||
**数据范围:** `'0'≤c≤'9'`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
7
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
12
|
||||
```
|
||||
|
||||
**解题思路:** 使用 `c-'0'` 把数字字符转换成整数。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
char c;
|
||||
cin >> c;
|
||||
int number = c - '0';
|
||||
cout << number + 5;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 直接计算 `c+5` 得到的是新的字符编码,不是题目需要的整数。
|
||||
|
||||
### 课后3:整数平均数【简单】
|
||||
|
||||
**题目描述:** 输入两个整数,输出它们的平均数,保留一位小数。
|
||||
|
||||
**输入格式:** 输入两个整数。
|
||||
|
||||
**输出格式:** 平均数,保留一位小数。
|
||||
|
||||
**数据范围:** 两数绝对值不超过 `10^6`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
2 5
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
3.5
|
||||
```
|
||||
|
||||
**解题思路:** 用 `(a+b)/2.0` 进行浮点除法。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int a, b;
|
||||
cin >> a >> b;
|
||||
cout << fixed << setprecision(1) << (a + b) / 2.0;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 除数写成 `2` 会进行整数除法,写成 `2.0` 才保留小数。
|
||||
|
||||
## 三、扩展练习(7题)
|
||||
|
||||
### 扩展1:向后移动一位【基础综合】
|
||||
|
||||
**题目描述:** 输入一个小写字母,输出字母表中的下一个小写字母;`z` 的下一个字母为 `a`。
|
||||
|
||||
**输入格式:** 一个小写字母。
|
||||
|
||||
**输出格式:** 平移后的字母。
|
||||
|
||||
**数据范围:** `a~z`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
z
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
a
|
||||
```
|
||||
|
||||
**解题思路:** 用 `(c-'a'+1)%26+'a'` 实现循环。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
char c;
|
||||
cin >> c;
|
||||
cout << (char)((c - 'a' + 1) % 26 + 'a');
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 单独写 `c+1` 无法处理 `z`。
|
||||
|
||||
### 扩展2:双向字母平移【基础综合】
|
||||
|
||||
**题目描述:** 输入一个大写字母、方向 `L` 或 `R` 和步数 `k`。向左或向右循环平移,输出结果。
|
||||
|
||||
**输入格式:** 依次输入一个大写字母、平移方向和移动位数。
|
||||
|
||||
**输出格式:** 平移后的大写字母。
|
||||
|
||||
**数据范围:** `0≤k≤10^9`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
B L 3
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
Y
|
||||
```
|
||||
|
||||
**解题思路:** 右移加 `k`;左移等价于加 `26-k%26`。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
char c, direction;
|
||||
long long k;
|
||||
cin >> c >> direction >> k;
|
||||
k %= 26;
|
||||
if (direction == 'L') k = (26 - k) % 26;
|
||||
cout << (char)((c - 'A' + k) % 26 + 'A');
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** C++ 中负数取模可能仍为负数,所以左移时先转成非负偏移量。
|
||||
|
||||
### 扩展3:两个字母的距离【中等】
|
||||
|
||||
**题目描述:** 输入两个同为大写的字母,输出从第一个字母向后循环移动到第二个字母所需的最少步数。
|
||||
|
||||
**输入格式:** 输入两个大写字母。
|
||||
|
||||
**输出格式:** 向后平移步数。
|
||||
|
||||
**数据范围:** `A~Z`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
X C
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
5
|
||||
```
|
||||
|
||||
**解题思路:** 计算 `(b-a+26)%26`。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
char a, b;
|
||||
cin >> a >> b;
|
||||
cout << (b - a + 26) % 26;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 加 26 是为了避免结果为负数。
|
||||
|
||||
### 扩展4:字母镜像【中等】
|
||||
|
||||
**题目描述:** 字母表两端互为镜像:`A↔Z`、`B↔Y`,小写字母同理。输入一个字母,输出它的镜像字母,并保持大小写。
|
||||
|
||||
**输入格式:** 一个英文字母。
|
||||
|
||||
**输出格式:** 镜像字母。
|
||||
|
||||
**数据范围:** 英文字母。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
C
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
X
|
||||
```
|
||||
|
||||
**解题思路:** 大写字母镜像为 `'A'+'Z'-c`,小写同理。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
char c;
|
||||
cin >> c;
|
||||
if (c >= 'A' && c <= 'Z') cout << (char)('A' + 'Z' - c);
|
||||
else cout << (char)('a' + 'z' - c);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 大写和小写必须使用各自的范围计算。
|
||||
|
||||
### 扩展5:凯撒口令【中等】
|
||||
|
||||
**题目描述:** 输入一个不含空格的字符串和非负整数 `k`。所有英文字母向后循环平移 `k` 位,保持大小写;数字和符号不变。
|
||||
|
||||
**输入格式:** 第一行输入一个不含空格的字符串;第二行输入向后平移的位数。
|
||||
|
||||
**输出格式:** 平移后的字符串。
|
||||
|
||||
**数据范围:** 字符串长度不超过 100,`0≤k≤10^9`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
Az-9
|
||||
2
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
Cb-9
|
||||
```
|
||||
|
||||
**解题思路:** 根据字符范围选择基准 `'A'` 或 `'a'`;其他字符原样保留。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
string s;
|
||||
long long k;
|
||||
cin >> s >> k;
|
||||
k %= 26;
|
||||
for (char &c : s) {
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
c = (c - 'A' + k) % 26 + 'A';
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
c = (c - 'a' + k) % 26 + 'a';
|
||||
}
|
||||
cout << s;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 平移后必须写回字符串;数字和符号不能参与字母公式。
|
||||
|
||||
### 扩展6:最短平移方向【略难】
|
||||
|
||||
**题目描述:** 输入两个大写字母。求从第一个字母循环平移到第二个字母的最少步数;若向左和向右步数相同,输出 `BOTH`,否则输出 `LEFT` 或 `RIGHT`,并输出步数。
|
||||
|
||||
**输入格式:** 输入两个大写字母。
|
||||
|
||||
**输出格式:** 方向和最少步数。
|
||||
|
||||
**数据范围:** `A~Z`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
A X
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
LEFT 3
|
||||
```
|
||||
|
||||
**解题思路:** 右移步数为 `(b-a+26)%26`,左移步数为 `(a-b+26)%26`,比较两者。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
char a, b;
|
||||
cin >> a >> b;
|
||||
int right = (b - a + 26) % 26;
|
||||
int left = (a - b + 26) % 26;
|
||||
if (left < right) cout << "LEFT " << left;
|
||||
else if (right < left) cout << "RIGHT " << right;
|
||||
else cout << "BOTH " << left;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 两个字母相同也属于左右步数相同,此时输出 `BOTH 0`。
|
||||
|
||||
### 扩展7:解密未知平移量【略难】
|
||||
|
||||
**题目描述:** 某个大写字母经过向后循环平移变成另一个大写字母。输入原字母和结果字母,求 `0~25` 范围内唯一的平移量 `k`;再输入第三个大写字母,按同样规则平移并输出。
|
||||
|
||||
**输入格式:** 依次输入原字母、加密后的字母和需要继续加密的字母。
|
||||
|
||||
**输出格式:** 第一行平移量 `k`;第二行第三个字母平移后的结果。
|
||||
|
||||
**数据范围:** `A~Z`。
|
||||
|
||||
**输入样例:**
|
||||
```text
|
||||
Y B Z
|
||||
```
|
||||
|
||||
**输出样例:**
|
||||
```text
|
||||
3
|
||||
C
|
||||
```
|
||||
|
||||
**解题思路:** 先由前两个字母计算 `k=(encoded-original+26)%26`,再把 `k` 应用于第三个字母。
|
||||
|
||||
**参考代码:**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
char original, encoded, target;
|
||||
cin >> original >> encoded >> target;
|
||||
int k = (encoded - original + 26) % 26;
|
||||
char answer = (target - 'A' + k) % 26 + 'A';
|
||||
cout << k << "\n" << answer;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**易错提醒:** 计算平移量和应用平移量使用的是同一个循环公式。
|
||||
Reference in New Issue
Block a user