循环的综合应用

官官方信息技术老师·18 页·深入(追求细节与边界)·0 次浏览·38 天前
嵌套循环边界分析终止条件

循环的综合应用

看完你能把嵌套、边界与终止条件拆干净,独立设计复杂循环

按 空格/→ 演示下一步

问一句
1 / 18 页

全部页面点击任意一页,跳回舞台从这页播放

嵌套循环边界分析终止条件

循环的综合应用

看完你能把嵌套、边界与终止条件拆干净,独立设计复杂循环

1第 1 页 · 循环的综合应用

三大循环回顾

上一页我们跑通了循环的实际问题,这一页先回头盘点手上的三件工具。选错循环就像拿勺子吃面条——也能吃,但很别扭。先把各自的脾气摸清楚,后面组合使用才顺手。

for:次数明确
知道要跑几圈时首选,初始化、条件、更新写在一行,一眼看清
while:先看条件
不知道跑几圈,先判断再动手;条件一开始就不成立则一次都不跑
do-while:先干再说
先执行一次再判断条件,至少跑一圈,适合菜单这种必须先展示的场合
选型口诀
数得清用 for,看情况用 while,必须来一次用 do-while
出行方式对应 →循环选型

已知路程选公交(for),看路况开车(while),先上车再补票(do-while)

2第 2 页 · 三大循环回顾

嵌套循环:行与列

上一页我们把三大循环都摸了一遍:它们都是「一圈一圈走」。可要是电影票按「几排几座」找位置,走完一排才能去下一排——这就要两个循环搭伙了。

外层循环管行
走完一整行,才挪到下一行,类似换排
内层循环管列
在一行里从头走到尾,找完每个座位
内快外慢
外层走 1 步,内层要走完一整圈
次数相乘
3 行每行 5 座,共执行 3×5=15 次
电影院找座位对应 →嵌套循环

找某排对应外层循环,排内逐座找对应内层循环

总次数=∑i=1mn=m×n\text{总次数}=\sum_{i=1}^{m} n = m \times n
3第 3 页 · 嵌套循环:行与列

什么是穷举

上页嵌套循环让循环里套循环,形成「外层走一步、内层走一圈」的结构。这正好能用来做一件事:把所有可能的组合一个不漏地试一遍——这就是穷举。

试遍所有可能
内外循环相乘,组合总数一张不漏全覆盖
前提是可列举
候选必须有限且能编号,否则试不完
代价随规模爆炸
每多一位数,尝试次数成倍增长
试密码锁对应 →穷举

密码锁逐位试组合对应循环逐个生成候选

3 位密码,每位 10 种⇒10×10×10=103 次尝试3 \text{ 位密码,每位 } 10 \text{ 种} \Rightarrow 10\times10\times10=10^3 \text{ 次尝试}
4第 4 页 · 什么是穷举

穷举的解题步骤

穷举所有答案,靠三步走:圈范围、定条件、留结果。

1
定枚举范围
确定候选解的循环区间,太大浪费时间,太小会漏解
2
写筛选条件
在循环体内用 if 判断,把不满足的候选逐一剔除
3
输出结果
条件成立的候选打印或记录,可能不止一个解
5第 5 页 · 穷举的解题步骤

穷举例题代码

python

用双层循环穷举公鸡母鸡小鸡数量,解百钱百鸡问题。

代码高亮加载中…

外层定公鸡数,内层遍历母鸡数,小鸡由总数量 100 直接推出——枚举空间从 10⁶ 压到约 700 次判断。

6第 6 页 · 穷举例题代码

数的排列组合问题

上一页我们用穷举解出了一道例题。现在换个更烧脑的场景:用数字 1、2、3 能组成多少个没有重复数字的三位数?一个个写出来太累,让循环替我们排队试。

百十个位各一重
三位数有百位、十位、个位,每位都从 1 到 3 取值
三层嵌套
百位循环套十位循环,十位循环再套个位循环
去重条件
用 if 判断三位互不相同,相同就跳过不输出
循环变量即答案
i、j、k 三个循环变量的当前值,正好拼成一个候选数
密码转盘锁对应 →三重循环枚举

转盘每一位独立转动,三位各转一轮就试遍所有组合

7第 7 页 · 数的排列组合问题

筛选满足条件的数

python

一段循环+拆位代码,找出100~999中所有水仙花数,看取余和整除怎么逐位拆数。

代码高亮加载中…

整除砍高位、取余留低位,两者配合拆出每一位,再立方求和穷举检验,命中即输出。

8第 8 页 · 筛选满足条件的数

自测:拆位判断

点击作答

要用循环把正整数 n 的各位数字从个位到高位逐个取出,循环体该写什么?

9第 9 页 · 自测:拆位判断

为什么只看末三位

乘法末三位的数学性质

为什么只看末三位
乘法末三位的数学性质
10第 10 页 · 为什么只看末三位

末三位求解代码

python

用「乘一次、截一次」的迭代写法求 a^n 的末三位,看清取余为什么不会丢信息。

代码高亮加载中…

乘法只受末三位影响: (x·a) 的末三位 = (x 的末三位 · a) 的末三位。所以每步 %1000 截断,数值永不超 300 万,任何 n 都不溢出。

11第 11 页 · 末三位求解代码

迭代过程可视化

从左到右跟一个变量走完循环:初始化、判断、执行、更新,每步看它的值变成多少。

图解渲染中…
b1:每圈都重新判断,为真才继续d1:i++ 是 i 自增 1,之后回到判断
12第 12 页 · 迭代过程可视化

从实心到空心

上一页我们用「行循环套列循环」打印出了实心矩形:每个位置都放星号。现在提一个小挑战——只要边框、不要填充,该怎么办?答案就藏在每个位置的行列编号里。

实心:无条件打星
不管行列是多少,每个位置都输出 *
空心:位置做判断
行是第一行/最后一行,或列是第一列/最后一列时才打星
其余位置打空格
不满足边界条件的位置输出空格,撑起矩形轮廓
if-else 二选一
每个位置在星号与空格之间做选择,逐格决定
描字帖的方格框对应 →空心矩形打印

笔尖只沿格子边缘描线,对应行列落在边界上才落星号

13第 13 页 · 从实心到空心

空心图案代码

python

看 if 判断如何让同一行循环里,只有边缘位置才打印星号。

代码高亮加载中…

把「边缘」翻译成坐标条件:i 是行、j 是列,首末行列打星,内部位置只打空格。

14第 14 页 · 空心图案代码

实心 vs 空心

两者代码几乎一样,却只差一个条件判断——搞清这行 if,就掌握了图案打印的核心。

实心图案
  • 每行输出所有列:j 从 1 到 n 全打印
  • 条件判断可有可无,逻辑最简单
  • 行列关系只决定行数,不筛选位置
空心图案
  • 先判断位置:j==1 或 j==n 才打印
  • 必须有 if,否则边界不成立时输出空格
  • 行列关系用于筛选:边界打印,内部留空
当每行所有位置都要输出时选实心;当只输出边界、内部填空格时选空心——区别就在那个 if 条件。
15第 15 页 · 实心 vs 空心

循环应用问题地图

从「循环」出发,按问题特征分四条路径:先判断目标是全找、挑着找、一步步推,还是摆形状,再选对应写法。

图解渲染中…
a1:不知道答案范围,把所有可能挨个试,如排列组合问题。b1:在穷举基础上加 if,只留下满足条件的数。c1:每轮结果作为下一轮输入,如由 n-1 位推末三位。d1:外层控制行、内层控制列,改变输出字符得空心。
16第 16 页 · 循环应用问题地图

本套图解要点

  • ✓三大循环可互换,for 适合已知次数
  • ✓嵌套循环:外层控行,内层控列
  • ✓穷举 = 全部试一遍 + 条件筛选
  • ✓拆位处理:取余拿低位,除法去位
  • ✓图案空心的关键是边界条件判断
延伸主题:break 与 continue 的提前退出循环效率与剪枝优化递归:自己调用自己的循环
17第 17 页 · 本套图解要点

课后思考

先自己想一会儿,再对照参考答案——问题没有唯一解。

1三大循环里,while 和 do-while 最大的差别是什么?什么场景下这个差别会真正影响结果?

参考答案关键在首次条件判断:do-while 先执行一次再判断,循环体至少跑一遍。想想菜单交互、输入校验,是不是天然要求'先做一次'?

2空心菱形图案里,判断打印空格还是星号的依据是什么?如果改成打印'斜线组成的 X',条件该怎么变?

参考答案空心图案靠'行列坐标满足边界/对角线条件才打印'。X 形是两条对角线:行号==列号,或行号+列号==宽+1。条件变了,循环框架不变。

3穷举时为什么只看末三位就够了?如果把'恰好出现'改成'至少出现一次',判断逻辑要调整吗?

参考答案乘方增长的规律:高位的值不影响后续只由低几位决定的部分(模运算性质)。'至少一次'只需去掉'最末尾'的位置限制,扫描所有窗口。

18第 18 页 · 课后思考