> **GESP等级：三级 | 考级考点：GESP Python 三级**

# 第19节 枚举法（穷举法）

**课程主题**：枚举算法思想入门
**课时**：60分钟
**授课对象**：7-10岁少儿
**教学形式**：五段式教学（10min导入 + 20min知识点 + 10min演示 + 15min实操 + 5min小测）

---

## 一、教学目标

### 知识与技能
1. 理解枚举法的核心思想——把所有可能都试一遍
2. 掌握枚举三步法：确定范围→遍历→判断
3. 能用for循环实现简单枚举
4. 学会用if条件在枚举中进行筛选
5. 了解枚举的优化思路——缩小范围

### 过程与方法
- 通过"试钥匙"的生活场景理解枚举
- 通过"三步法"建立枚举的思维框架
- 通过turtle可视化看到枚举的执行过程

### 情感态度价值观
- 培养"不放弃、逐个尝试"的耐心品质
- 理解计算机擅长做重复劳动
- 体会"暴力破解"背后的思维美感

---

## 二、教学重难点

### 重点
- 枚举三步法：范围→遍历→判断
- for循环与if判断的组合使用
- 枚举在实际问题中的应用

### 难点
- 如何确定枚举范围（从哪找到哪找）
- 如何设计判断条件
- 枚举优化思路（缩小范围减少计算量）

---

## 三、教学准备

| 项目 | 内容 |
|------|------|
| 硬件 | 电脑（每生一台）、投影仪 |
| 软件 | Python IDLE 或 VS Code |
| 教具 | 一把锁和一堆钥匙（或图片）、计数小棒 |
| 素材 | 无特殊文件需求 |

---

## 四、教学过程

---

### 第一阶段：故事导入（10分钟）

#### 1.1 "钥匙试锁"故事

**老师**：（拿出一把锁和一大串钥匙）小朋友们，如果我锁了自行车，但是钥匙混在这一大串里面了，怎么办？

**学生**：一把一把试！

**老师**：对了！这就是我们今天要学的——**枚举法**！也叫穷举法！
就是把所有可能的情况都试一遍，总能找到对的！

#### 1.2 生活场景枚举

**老师引导**让学生列举生活中的枚举场景：

| 场景 | 枚举什么？ | 范围 |
|------|-----------|------|
| 找钥匙开锁 | 一把把试钥匙 | 所有钥匙 |
| 找丢失的橡皮 | 检查每个抽屉 | 所有抽屉 |
| 破解密码 | 试所有数字组合 | 0000~9999 |
| 找全班最高的人 | 一个个量身高 | 全班同学 |

#### 1.3 身体锚点

**"一个个数"动作**：
- 手在桌上一个个点过去，嘴里念"1、2、3、4..."
- 点到符合条件的就握拳举起来！
- 全班一起做两遍！

#### 1.4 引出课题

"今天我们就来学这种'笨但有用'的方法——枚举法！Python最擅长做这种重复劳动了！"

---

### 第二阶段：知识点讲解（20分钟）

---

#### 2.1 枚举三步法

**老师板书**：

```
枚举三步走：
  ① 确定范围 —— 在哪些里面找？
  ② 遍历 —— 用for循环一个个试
  ③ 判断 —— 符合条件的留下！
```

**口诀**：
> "枚举枚举，一个一个来"
> "for循环里加if，符合条件的就出来"

**三步法口诀**：
> "范围→遍历→判断，三步搞定枚举法"

---

#### 2.2 第一步：确定范围

**确定"从哪里找到哪里"**。

**例子**：
- 找1-100之间的偶数 → 范围是 1到100
- 找三位数中的水仙花数 → 范围是 100到999
- 找1-50之间的质数 → 范围是 2到50

```python
# 范围就是 for 循环的 range
for i in range(1, 101):   # 范围：1~100
    # 遍历每个数
```

**小技巧**：范围定得越小，程序跑得越快！

---

#### 2.3 第二步：遍历 —— for循环

**遍历** = 一个接一个地检查

```python
# 遍历1到100
for num in range(1, 101):
    print(num)   # 打印每个数
```

**比喻**：遍历就像点名——老师拿着花名册，一个个念名字。

---

#### 2.4 第三步：判断 —— if条件

在遍历的过程中，用if判断是否符合条件。

```python
# 找1-100之间的偶数
for num in range(1, 101):
    if num % 2 == 0:       # 判断：能被2整除
        print(num)         # 符合条件的打印出来
```

**完整流程**：
```
范围：[1, 2, 3, ..., 100]
         ↓ 遍历
    num = 1 → 1%2!=0 → 不要
    num = 2 → 2%2==0 → 要！打印
    num = 3 → 3%2!=0 → 不要
        ...
```

---

#### 2.5 经典问题1：水仙花数

**故事**："水仙花数"这个名字来自于一个古老的数学谜题。

**定义**：三位数，各位数字的立方和等于它本身。
> 153 = 1³ + 5³ + 3³ = 1 + 125 + 27 = 153

**分析步骤**：
```
① 范围：所有的三位数 100~999
② 遍历：for i in range(100, 1000)
③ 判断：百位³ + 十位³ + 个位³ == 本身
```

**如何取各位数字**：
```python
num = 153
bai = num // 100        # 百位：1
shi = (num // 10) % 10  # 十位：5
ge = num % 10           # 个位：3
```

**完整代码**：
```python
print("水仙花数有：", end="")
for num in range(100, 1000):
    bai = num // 100
    shi = (num // 10) % 10
    ge = num % 10
    if bai**3 + shi**3 + ge**3 == num:
        print(num, end=" ")
# 输出：153 370 371 407
```

---

#### 2.6 经典问题2：百钱百鸡

**故事**：中国古代数学家张丘建提出的问题。
> 公鸡5元一只，母鸡3元一只，小鸡1元3只。
> 用100元买100只鸡，怎么买？

**分析**：
- 公鸡最多买 100//5 = 20只
- 母鸡最多买 100//3 = 33只
- 小鸡数量 = 100 - 公鸡 - 母鸡
- 总钱数 = 公鸡*5 + 母鸡*3 + 小鸡/3 = 100

**枚举代码**：
```python
print("百钱百鸡的买法：")
for gong in range(0, 21):       # 遍历公鸡数量
    for mu in range(0, 34):      # 遍历母鸡数量
        xiao = 100 - gong - mu   # 小鸡数量
        if gong*5 + mu*3 + xiao/3 == 100:
            print(f"公鸡{gong}只，母鸡{mu}只，小鸡{xiao}只")
```

**老师解释**：这里用了**两层循环**——先固定公鸡数量，再试母鸡数量，小鸡自动算出来。

---

#### 2.7 经典问题3：找完美数

**定义**：一个数等于它的所有因子（除了自身）之和。
> 6 = 1 + 2 + 3（6的因子有1,2,3,6，去掉自身6）
> 28 = 1 + 2 + 4 + 7 + 14

**分析**：
```
① 范围：1~10000（先找小的）
② 遍历：每个数找它的因子
③ 判断：因子和是否等于自身
```

**代码**：
```python
print("完美数有：", end="")
for num in range(2, 10001):
    sum_factor = 0
    for i in range(1, num):
        if num % i == 0:
            sum_factor += i
    if sum_factor == num:
        print(num, end=" ")
```

---

#### 2.8 优化思路：缩小范围

**为什么要优化？**
- 枚举范围太大时程序跑得很慢
- 找到规律缩小范围，让程序更快

**例子**：找完美数时，因子只要检查到 num//2 就够了
```python
# 优化前：检查 1~num-1
for i in range(1, num):

# 优化后：检查 1~num//2
for i in range(1, num // 2 + 1):
```

**记忆口诀**：
> "枚举虽然好，范围别太大"
> "能小就小，能减就减"

---

### 第三阶段：教师演示（10分钟）

#### 3.1 演示1：基础枚举——找偶数

```python
# 找1-20之间的偶数
print("1-20之间的偶数：")
for i in range(1, 21):
    if i % 2 == 0:
        print(i, end=" ")
print()
```

**老师**："看，for循环一个个检查，遇到偶数就打印。"

#### 3.2 演示2：水仙花数

运行 `02_枚举法.py` 的水仙花数功能，展示枚举过程。

#### 3.3 演示3：turtle枚举可视化

运行turtle演示，在屏幕上看到所有数字，符合条件的标绿色，不符合标红色。

---

### 第四阶段：学生实操（15分钟）

#### 实操任务1：找倍数（5分钟）

**要求**：
1. 枚举1-50之间的数
2. 找出所有**既是3的倍数又是5的倍数**的数
3. 打印出来

**参考代码**：
```python
print("1-50之间既是3又是5的倍数：")
for num in range(1, 51):
    if num % 3 == 0 and num % 5 == 0:
        print(num, end=" ")
```

#### 实操任务2：猜数字（5分钟）

**要求**：
1. 程序想一个1-100之间的数字（用 random）
2. 你每次猜一个，程序告诉你是大了还是小了
3. 直到猜对为止
4. 统计猜了几次

**参考代码**：
```python
import random
secret = random.randint(1, 100)
count = 0
while True:
    guess = int(input("猜一个数(1-100)："))
    count += 1
    if guess == secret:
        print(f"猜对了！用了{count}次")
        break
    elif guess < secret:
        print("小了")
    else:
        print("大了")
```

#### 实操任务3：百钱百鸡（5分钟）

让学生自己写出百钱百鸡的枚举程序，按照三步法写注释。

```python
# 第一步：确定范围
# 第二步：遍历（两层循环）
# 第三步：判断
```

---

### 第五阶段：小测验（5分钟）

#### 题目1（选择题）
枚举法的核心思想是什么？
A. 找规律直接算  B. 把所有可能都试一遍  C. 猜一个答案  D. 用公式计算

**答案**：B

#### 题目2（填空题）
枚举三步法是：①确定____ ②____ ③____

**答案**：范围、遍历、判断

#### 题目3（判断题）
枚举的范围越大，程序跑得越快。（对/错）

**答案**：错。范围越大，要试的次数越多，程序越慢。

#### 题目4（代码题）
看代码，写出输出结果：
```python
for i in range(1, 11):
    if i % 2 == 0:
        print(i, end=" ")
```

**答案**：2 4 6 8 10

#### 题目5（应用题）
要用枚举法找1-100之间的质数（只能被1和自身整除），判断条件应该怎么写？
A. if num % 2 == 0  B. if num % i == 0  C. 需要检查能否被2到num-1之间的数整除

**答案**：C

---

## 五、板书设计

```
+========================================+
|          枚举法（穷举法）                |
+========================================+
|                                         |
|  三步法：                               |
|  ① 确定范围 → for循环的range           |
|  ② 遍历 → for循环一个个检查            |
|  ③ 判断 → if条件筛选                   |
|                                         |
|  经典问题：                             |
|  · 水仙花数：153=1³+5³+3³              |
|  · 百钱百鸡：公鸡5母鸡3小鸡1/3        |
|  · 完美数：6=1+2+3                     |
|                                         |
|  优化：缩小范围！                       |
+========================================+
```

---

## 六、课后作业说明

参见《课后练习_第19节.md》文件。

**作业要点**：
1. 基础枚举练习——巩固三步法
2. 水仙花数和百钱百鸡——经典问题应用
3. 创意挑战——枚举密码破解

---

## 七、常见错误与应对

| 错误 | 原因 | 解决方法 |
|------|------|---------|
| 范围不对（差1） | range结束值理解错误 | range(a,b)是[a,b)左闭右开 |
| 循环层数混乱 | 嵌套循环逻辑不清 | 用纸笔画流程图 |
| 判断条件写反 | 大于小于搞混 | 用具体数字测试 |
| 忘了缩小枚举范围 | 不知道可以优化 | 考虑上下限 |

---

## 八、教学反思（教师填写）

| 维度 | 评价 | 备注 |
|------|------|------|
| 导入环节 | ___/5 | 钥匙故事是否吸引 |
| 三步法讲解 | ___/5 | 学生是否理解 |
| 经典问题 | ___/5 | 水仙花数兴趣度 |
| 实操环节 | ___/5 | 完成度 |
| 小测 | ___/5 | 正确率 |

---

## 九、拓展延伸

### 枚举的应用领域
- 密码破解（暴力破解）
- 搜索算法（广度优先/深度优先）
- 人工智能中的博弈树搜索
- 数独求解器

### 家庭互动
- 和爸妈一起算：家里的门锁密码有多少种可能？
- 用枚举法帮妈妈找出购物最优方案

---

*教案编写日期：2026年6月*
*适用阶段：19_文件与算法入门*
