简介:这份资源是粤教版2019信息技术必修1第三章《算法基础》的配套教学课件,面向高中信息技术教师备课授课与高一学生同步复习使用,也可供初学者梳理算法入门知识。内容围绕算法定义与五大特征展开,串联自然语言、流程图、伪代码三种描述方式,并以过河问题、鸡兔同笼两个经典案例演示从分析问题、设计算法到编写程序、调试运行的完整流程,还附有流程图基本符号与程序三种基本结构的讲解,以及用Python实现鸡兔同笼求解的代码示例。资源压缩包内共1个pptx文件,约8.46MB,页面以目录导航配合分步标题组织,便于课堂投屏逐节讲解或课后按模块自学。已有110人学习,适合需要快速搭建课堂主线、对照知识点查漏补缺的师生参考借鉴。
1. 牧羊人过河与鸡兔同笼:算法基础这份课件到底解决什么问题
翻到粤教版2019必修1第三章「算法基础」这套PPT,第一反应是案例选得很克制:一个是牧羊人带羊、狼、白菜过河,一个是鸡兔同笼,都不需要写复杂代码,却把「算法是什么、怎么描述、怎么落地成程序」这条主线串完了。
课件主干包含算法定义与五大特征、自然语言/流程图/伪代码三种描述方式、流程图符号与顺序选择循环三种结构,以及鸡兔同笼从方程组推导到Python程序、再到调试运行的完整链路。中学信息技术课可以直接拿去上;准备信息技术水平考试的人能拿它当复习骨架;刚学编程的自学者也可以补上「先想清楚再写代码」这一课。
反直觉的一点在于,这节课的落点不是会不会写Python,而是能不能把解决问题的步骤说清楚。代码只是最后一步的翻译结果。
2. 算法五大特征与三种描述方式的边界:自然语言、流程图、伪代码怎么选
2.1 五大特征当成检查清单用,而不是背诵条目
课件给的定义是:算法是在有限步骤内求解某一问题所使用的一组定义明确的规则;通俗说法是能被机械执行的动作或指令的有穷集合。这句话里藏着三个关键词——有限、明确、可机械执行,正好对应后面的特征条目。
确定性指每一步都有明确的操作。过河问题里「第一步:人和羊过河,人返回,留下羊」是确定的;如果写成「想办法先把危险的一方带过去」,就没法机械执行。有穷性指步骤数量有限,而且能在有限时间内结束,写循环时尤其要注意,一个 while 条件永远为真的程序不是算法,只是没终止的程序。可行性指每一步都能拆成基本操作,2a - b/2是四则运算,可行;「求出所有可能解里最优的那个」在没定义清楚搜索范围之前就不可行。数据输入是算法处理的对象,鸡兔同笼里就是头数 a 和脚数 b;数据输出是算法给出的结果,也就是解出的 x、y。
课件里的判断题值得反复用。「算法就是解决问题的方法」判错,因为方法可以笼统,算法必须是有限、确定、可执行的步骤序列。「每个问题都有固定唯一的算法」也判错,鸡兔同笼既可以用二元一次方程组直接解,也可以枚举所有可能的鸡数逐个试,两种算法在效率上的差距,正好是后面讲算法效率的伏笔。
提示:判断题不要只对答案。让学生说出另外几个选项错在哪里,比判对错有效得多。
2.2 自然语言描述:门槛最低,歧义最多
鸡兔同笼的自然语言算法是五步:输入 a 和 b 的值;求 x = 2a - b/2;求 y = b/2 - a;输出 x 和 y 的值;结束。谁都能看懂,这是它最大的优势,也是它唯一的优势。
局限有三条:语句冗长;容易产生二义性,比如「求 x = 2a - b/2」里其实已经混进了数学符号,严格说不再是纯自然语言;不方便直接翻译成机器语言。还有一个细节值得在课上点一下——第二步和第三步的顺序可以互换,因为两者互不依赖,但第五步「结束」不能提前,这就是顺序结构里「有依赖的步骤不能随意调换」的最小例子。
2.3 伪代码描述:向机器语言推进一步
伪代码用介于自然语言和计算机语言之间的文字和符号描述算法,不关心类型声明和语法细节。
# 伪代码:鸡兔同笼求解,用 Python 风格书写,但忽略语法细节 input a, b # 输入头数和脚数 x = 2 * a - b / 2 # 由方程组消元得到鸡的数量 y = b / 2 - a # 得到兔的数量 print x, y # 输出结果逻辑说明:伪代码保留了输入、赋值、运算、输出这些语义,省掉了类型转换、变量声明这些语言细节。参数说明:a 表示头数,b 表示脚数,x、y 是待求的鸡数和兔数。之所以写成赋值表达式而不是中文句子,是为了让每一步都可执行、可核对。
写伪代码时最容易踩的坑是把=当数学等号。数学里x = 2a - b/2描述的是等式关系,伪代码里=是赋值动作,右边先算完再写进左边,方向反了语义就错了。
2.4 三种描述方式的取舍
| 描述方式 | 优点 | 局限 | 典型使用场景 |
|---|---|---|---|
| 自然语言 | 无学习成本,便于口头交流 | 冗长、可能出现歧义 | 课堂分析问题、小组讨论阶段 |
| 流程图 | 结构清晰,分支与循环一目了然 | 符号多,复杂算法图形过大 | 讲清控制结构、考试画图题 |
| 伪代码 | 接近程序,便于直接翻译 | 需要约定书写规范 | 从算法设计过渡到编码 |
实际推进顺序一般是:先用自然语言把思路讲一遍确认没问题,再画流程图检查控制流有没有漏洞,最后写伪代码准备落地。反过来做,先写代码再补描述,边界情况往往就漏掉了。
3. 流程图符号体系与顺序、选择、循环三种结构的画法
3.1 六个基本图形符号与进出线规则
| 图形 | 符号名称 | 说明 | 进出线约束 |
|---|---|---|---|
| 圆角矩形或椭圆 | 起止框 | 表示算法的开始或结束 | 开始框一流出,结束框一流入 |
| 平行四边形 | 输入/输出框 | 标明输入或输出的内容 | 一流入、一流出 |
| 矩形 | 处理框 | 标明要执行的处理动作 | 一流入、一流出 |
| 菱形 | 判定框 | 标明判定条件,框外标 T/F 流向 | 一流入、两流出 |
| 箭头 | 流线 | 表示从一个框到另一个框的流向 | 连接用 |
| 小圆圈 | 连接圈 | 表示流向的出口或入口连接点 | 跨页或避免线条交叉时使用 |
判定框是唯一允许两条流出线的符号,但同一时刻只有一条起作用。这条规则看着简单,手绘时标反 T/F 的情况非常普遍。
3.2 顺序、选择、循环三种基本结构的代码对照
顺序结构从上到下依次执行,鸡兔同笼的主流程就是纯顺序结构,没有分支也没有重复。
选择结构可以拿课件里那个例子讲:判定条件是 a > b,取 a = 5、b = 7,T 分支输出 a、F 分支输出 b,最后结果应该是 7。
# 选择结构:判定框对应 if,两条流出线对应两个分支 a = 5 b = 7 if a > b: print(a) # 条件为真走这条 else: print(b) # 条件为假走这条,实际输出 7逻辑说明:if/else与流程图上的判定框一一对应,条件写在判定框内,T、F 标在两条流出线上。参数说明:a、b 是参与比较的两个值,条件 a > b 在任何一侧分支执行前先求值,只会走其中一条。
循环结构在过河问题里其实也出现了——「载货过河、人返回」这套动作重复了多次,只是课件把它拆成了四个步骤。鸡兔同笼如果换成枚举法,循环就绕不开了。
# 循环结构:枚举所有可能的鸡数,找到脚数匹配的那一组 heads, feet = 35, 94 for chickens in range(heads + 1): # 鸡的数量从 0 试到头数 rabbits = heads - chickens # 兔的数量由头数推出 if 2 * chickens + 4 * rabbits == feet: print('鸡', chickens, '兔', rabbits)逻辑说明:for同时承担了判定和回边两个角色,range(heads + 1)提供循环变量序列,if在循环体内做判定,命中就输出。参数说明:heads、feet 是题目给定的头数和脚数,chickens 是循环变量。这段代码输出鸡 23 只、兔 12 只,与方程组直接求解的结果一致。流程图上的关键是那条回边:没有从循环体末尾回到判定框的流线,图就退化成顺序结构了。
3.3 从自然语言步骤到流程图的转换套路
我一般按四步走:把自然语言算法的每一步编号,标出哪些是输入输出、哪些是处理、哪些是判断;确定开始和结束,先把主干画出来;把判断和重复拎出来,换成判定框和回边;最后逐个检查框的进出线数量。
鸡兔同笼的框连接关系可以直接列成表,照着连线比空手画快得多。
| 框编号 | 类型 | 内容 | 后继 |
|---|---|---|---|
| B1 | 起止框 | 开始 | B2 |
| B2 | 输入框 | 输入 a, b | B3 |
| B3 | 处理框 | x = 2a - b/2 | B4 |
| B4 | 处理框 | y = b/2 - a | B5 |
| B5 | 输出框 | 输出 x, y | B6 |
| B6 | 起止框 | 结束 | 无 |
3.4 手绘和检查控制流时最常见的四类错误
第一类是判定框只画了一条流出线,或者 T/F 标反。第二类是符号用错,输入输出用了矩形,处理步骤用了平行四边形,这种情况在批改作业时一眼能看出来。第三类是循环缺回边,或者回边接到了处理框而不是判定框上,画出来看着像循环,控制流实际是错的。第四类是结束框后面还接了流线,或者连接圈被当成普通节点到处乱用。
注意:检查流程图最快的办法是顺着流线走一遍,看每个框是不是都「进得来、出得去」,起止框按定义例外。
4. 鸡兔同笼的完整求解链路:方程组、伪代码到 Python 程序
4.1 建模:头脚条件怎么变成二元一次方程组
设鸡 x 只,兔 y 只,头数 a,脚数 b。每只鸡一个头两只脚,每只兔一个头四只脚,于是得到两个方程:x + y = a,2x + 4y = b。
消元过程要写清楚才不算背公式。第一式两边乘 2 得 2x + 2y = 2a,用第二式减它得 2y = b - 2a,所以 y = b/2 - a;代回第一式得 x = a - y = 2a - b/2。课件里直接给出这两个结果,把推导补上,学生才不会当成咒语记。
代入 a = 35、b = 94:y = 94/2 - 35 = 12,x = 70 - 47 = 23。验算一遍:23 + 12 = 35,2×23 + 4×12 = 46 + 48 = 94,两组条件都满足。这里还有个隐含条件值得提:脚数 b 必须是偶数,且解出的 x、y 都不能为负,否则题目本身不成立。
4.2 算法步骤与流程图的一一对应
| 步骤 | 内容 | 对应符号 |
|---|---|---|
| 1 | 输入 a、b | 输入/输出框(平行四边形) |
| 2 | x = 2a - b/2 | 处理框(矩形) |
| 3 | y = b/2 - a | 处理框(矩形) |
| 4 | 输出 x、y | 输入/输出框(平行四边形) |
| 5 | 结束 | 起止框 |
这五步是纯顺序结构,所以在图上是一条直线走到底。判断该不该画判定框有个简单标准:步骤里出现条件就画菱形,没出现就别画。
4.3 从伪代码到可运行的 Python
# 鸡兔同笼:输入头数和脚数,输出鸡和兔的数量 a = int(input('请输入头数:')) # input 返回字符串,int() 转成整数 b = int(input('请输入脚数:')) x = int(2 * a - b / 2) # 计算鸡的数量 y = int(b / 2 - a) # 计算兔的数量 print("鸡的数量为", x) print("兔的数量为", y)逻辑说明:前两行完成读入和类型转换,中间两行各做一次算术运算,最后两行输出。参数说明:input()拿到的是字符串,必须用int()转换后才能参与算术;/在 Python 3 里得到浮点数,int()把结果截断成整数,35 和 94 这组数据不会出现精度问题。
请输入头数:35 请输入脚数:94 鸡的数量为 23 兔的数量为 124.4 输入校验与边界处理
上面这段能跑,但遇到奇数脚数、负数,或者脚数明显不合理的情况,会输出负数甚至不存在的解。把它改成带判断的版本:
def solve(heads, feet): """返回 (鸡数, 兔数),输入不合法时返回 None""" if feet % 2 != 0 or feet < 2 * heads or feet > 4 * heads: return None # 脚数为奇数或超出合理区间 rabbits = feet // 2 - heads # 用整除,表达这里本就是整数运算 chickens = heads - rabbits return chickens, rabbits for h, f in [(35, 94), (35, 95), (10, 20), (10, 45)]: print(h, f, '->', solve(h, f))逻辑说明:feet % 2 != 0排除奇数脚数,feet < 2 * heads排除脚太少,feet > 4 * heads排除脚太多,三种情况统一返回 None。参数说明:heads、feet 是形参,//是整除运算符,比int(... / ...)更能表达「这里本来就是整数」这层意思。
35 94 -> (23, 12) 35 95 -> None 10 20 -> (10, 0) 10 45 -> None(10, 20)对应 10 只鸡、0 只兔,是合法解。这种情况课件里没提,但学生一定会问,提前用一张边界测试表说清楚更省事。
5. 语法错误、逻辑错误与交叉验证:把程序验算做扎实
5.1 两类错误的分工:语法错误交给解释器,逻辑错误交给验算
课件最后提到了两类错误,值得展开。语法错误计算机能直接指出,少个右括号、input拼错,解释器会给出文件名和行号,照着改就行。逻辑错误计算机一句怨言都没有,程序照常跑完,只是结果是错的——把x = 2*a - b/2写成x = 2*a - b*2,Python 会安静地输出一个荒谬的答案。
抓逻辑错误靠手工验算,构造几组已知答案的测试数据,算一遍再和程序输出比对,比对代码本身有用得多。
| 头数 a | 脚数 b | 期望鸡 x | 期望兔 y | 说明 |
|---|---|---|---|---|
| 35 | 94 | 23 | 12 | 课件原题 |
| 1 | 4 | 0 | 1 | 全是兔 |
| 1 | 2 | 1 | 0 | 全是鸡 |
| 10 | 45 | 无解 | 无解 | 脚数为奇数 |
5.2 用枚举法交叉验证公式法
更可靠的一条路是让两个独立算法互相对账。枚举法不依赖任何公式,按定义逐个试,结果天然可信:
# 用枚举结果校验公式法,两者不一致就说明公式实现有问题 def brute_force(heads, feet): for r in range(heads + 1): # 兔的数量从 0 试到头数 c = heads - r # 鸡由头数反推 if 2 * c + 4 * r == feet: return c, r return None assert solve(35, 94) == brute_force(35, 94) == (23, 12)逻辑说明:range(heads + 1)覆盖 0 到头数的全部可能,找到第一组满足脚数条件的就返回。用assert把两种算法的结果绑在一起,公式写错会立刻抛 AssertionError,而不是等到人工比对时才发现。参数说明:heads、feet 与 solve 函数保持一致,便于直接对拍。
这个对拍过程在课堂上还有第二个用途:讲清同一个问题可以有不同的算法。枚举是随头数线性增长的循环,公式法是常数次运算,头数越大差距越明显。信息技术水平考试和各类信息技术笔试的算法基础题,很多时候就是把这层「等价性与效率差异」做成选项来考。日常调试再补一个小习惯——在关键步骤插一句print(x, y),比盯着代码找问题快得多,这也是课件里「调试运行程序」这一步最实在的落地方式。
本文还有配套的精品资源,点击获取