ARTICLE · 1145235
信息学社团开课啦~|习题讲解(洛谷配套顺序结构)
00
写在前面
洛谷上有配套的顺序结构专项练习。讲完顺序结构就可以给学生进行布置了。规定好完成时间、讲解时间。通过这一环节,就能看出哪些孩子能真正学得进去、有继续培养的潜力。https://www.luogu.com.cn/training/100#problems

01
教学目标
知识目标:
巩固顺序结构的核心工具:int、cin、cout、double、char、+ - * / %。
掌握新工具:sqrt() 开平方、ceil() 向上取整、fixed << setprecision(n)、char 逐字符读入。
理解整数向上取整公式
(a + b - 1) / b与ceil()的等价适用条件。
能力目标:
能够把生活问题(时间计算、体积计算、面积计算)翻译成顺序结构的算式。
能够根据题目要求选择合适的变量类型和输出格式。
学会利用取模 + 固定公式,在不用分支循环的情况下处理时间跨天的负数溢出问题
素养目标:
体会“先想清楚、再动手写”的编程习惯。
感受顺序结构“从上往下一条一条执行”的简洁之美。
建立“工具不够用就现场学新工具”的学习信心。
02
教学重难点
重点:
① 根据题目选择变量类型;
② fixed << setprecision(n) 控制小数位数;
③ ceil() 向上取整的应用场景
难点:
① P5707 中取模运算处理跨天情况;
② P5705 中“字符”与“整数”的区别;
③ 向上取整的必要性理解
03
习题精讲
1.P5705 数字反转
第一:给思路
题目输入一个浮点数,比如 123.4,要求翻转成 4.321。
关键观察:输入的数一定不小于 100、小于 1000,小数点后只有 1 位,所以格式固定是 abc.d,一共 5 个字符。
方法一(推荐):把它当成 5 个字符,用 5 个 char 变量一个一个读进来,倒着输出。
方法二(不推荐):乘以 10 再拆位。这个方法有浮点精度隐患,比如 123.4 在计算机里可能存成 123.3999...,乘 10 后截断成 1233,拆位就全错了。
注意:如果用 cin >> double 再拆数字,浮点误差是真实大坑,这也是本题推荐字符法的核心原因。
第二:学生思考并尝试的去完成
第三:教师巡查,并提供相应的步骤给基础薄弱的学生
包含头文件 <iostream>。
定义五个 char 变量,比如 a、b、c、d、e。
用 cin 依次读入五个字符。
用 cout 倒序输出这五个字符,顺序是 e、d、c、b、a。
第四:老师讲解

逐行讲解:
char 是字符类型,存单个字符,用单引号表示。
cin >> a >> b >> c >> d >> e; 输入 123.4 时依次读入 '1'、'2'、'3'、'.'、'4'。
读入的不是五个整数,而是五个字符。
cin >> 读 char 时会自动跳过空格和换行,但本题输入没有空格,所以 5 个字符能连读。
cout << e << d << c << b << a; 倒序输出得到 4.321。
2.P5706 再分肥宅水
第一:给思路
有 t 毫升饮料,分给 n 名同学,每名同学需要 2 个杯子。
第一问:t / n,t 是 double,n 是 int,结果是小数,保留 3 位。
第二问:n * 2,整数运算。
第二:学生思考并尝试地去完成
第三:教师巡查,并提供相应的步骤给基础薄弱的学生
包含头文件 <iostream> 和 <iomanip>。
定义一个 double 变量 t 和一个 int 变量 n,读入。
第一行输出:用 cout << fixed << setprecision(3) 保留 3 位小数,输出 t / n,然后换行。
第二行输出:n * 2,然后换行。
第四:老师讲解

要点:
fixed << setprecision(3) 保留 3 位小数,需要 #include <iomanip>。
漏写 fixed 会变成 3 位有效数字,不是 3 位小数。
t 定义成 int 会导致整数除法,小数被截断。
3.P5708 三角形面积
第一:给思路
海伦公式分两步:先算半周长 p = (a+b+c)/2,再开平方 S = sqrt(p(p-a)(p-b)(p-c))。
新工具:sqrt() 开平方,需要 #include <cmath>。
第二:学生思考并尝试地去完成
第三:教师巡查,并提供相应的步骤给基础薄弱的学生
包含三个头文件:<iostream>、<iomanip>、<cmath>。
定义三个 double 变量 a、b、c,读入三边。
计算半周长 p。注意除以 2.0,保证浮点数除法。
用 sqrt() 计算面积。把 p * (p - a) * (p - b) * (p - c) 作为 sqrt 的参数,注意括号配对。
用 cout << fixed << setprecision(1) 保留 1 位小数输出面积。
第四:教师讲解

演示:
输入 3 4 5,p = 6.0,area = sqrt(36.0) = 6.0,输出 6.0。
4.P5707 上学迟到
第一:给思路
距离 s 米,速度 v 米/分钟,额外 10 分钟垃圾分类,8:00 到校。
第一步:走路时间 s / v,不足 1 分钟要算 1 分钟,用 ceil() 向上取整。
新工具:ceil() 向上取整,需要 #include <cmath>。
第二步:总时间 = ceil(s/v) + 10。
第三步:从 8:00(即 480 分钟)往前推。
关键问题:如果总时间很大,480 减完变成负数怎么办?比如总时间 500,480 - 500 = -20,说明要跨天——可能是前一天,也可能是好几天前。
但我们不需要判断提前了几天,因为钟表每 1440 分钟循环一次:
先 total % 1440 折算到一天之内
再 (480 - t + 1440) % 1440 算出门时间
利用取模公式,不需要 if 判断就能自动处理跨天,无论需要往前推多少天。
对照写法:
ceil(s/v) 也可以用整数实现:(s + v - 1) / v。两者结果一样,整数方法不需要 <cmath>。本课先用 ceil,因为它更直观。
注意:这个公式只在 s、v 都是正整数时才和 ceil 等价,遇到负数不能用。
第二:学生思考并尝试地去完成
第三:教师巡查,并提供相应的步骤给基础薄弱的学生
包含头文件 <iostream> 和 <cmath>。
定义两个 int 变量 s、v,读入。
计算总分钟数 total:走路时间用 ceil(s * 1.0 / v) 向上取整,再加 10 分钟。
把总时间折算到一天之内:t = total % 1440。
从 8:00(480 分钟)往前推,用 (480 - t + 1440) % 1440 算出出门时间 leave。
把 leave 拆成小时 h 和分钟 m:h = leave / 60,m = leave % 60。
手动补零输出:小时和分钟都要两位数,可以用 h / 10、h % 10、m / 10、m % 10 拼出来。
第三:老师讲解

逐行讲解:
ceil(s * 1.0 / v):s * 1.0 变成 double,除以 v 得小数,ceil 向上取整。
+ 10:垃圾分类时间。
total % 1440:把总时间折算到一天之内。
(480 - t + 1440) % 1440:从 480 往前减 t,加 1440 再取余,结果在 0 到 1439 之间。
h / 10 << h % 10:手动补零。比如 h = 7,输出 07。
演示:
输入 100 99:
输出 07:48。
5.B2029 大象喝水
第一:给思路
大象要喝 20 升 = 20000 立方厘米。桶是圆柱体,体积 = 3.14 × r × r × h。
用 20000 除以桶的体积,除不尽要向上取整,用 ceil()。
第二:学生思考并尝试地去完成
第三:教师巡查,并提供相应的步骤给基础薄弱的学生
请按照以下步骤,自己写出完整程序:
包含头文件 <iostream> 和 <cmath>。
定义两个 int 变量 h、r,读入深度和半径。
计算每桶体积 v:用 3.14 * r * r * h,结果存到 double 变量里。
计算需要多少桶:用 ceil(20000.0 / v) 向上取整。
把结果存到 int 变量 ans,输出 ans。
第三:教师讲解

要点:
3.14 * r * r * h 中 3.14 是 double,所以结果是 double。
ceil() 返回 double,它的结果本身是一个整数对应的浮点数(如 3.0),赋值给 int 时会做隐式类型转换,得到整数 3
int(20000.0 / v) 是向下取整,会少算一桶,必须用 ceil。
演示:
输入 23 11,输出 3。

本课小结
fixed + setprecision(n) 需要头文件 <iomanip>;ceil 在 <cmath>,返回 double;ceil(小数):通用;(a+b-1)/b:仅 a,b 为正整数时等价;
