这题到底在考什么
按奇偶规则把 n 变到 1,边变边存整个序列,最后从后往前输出。
对象
保留当前 n 和保存路径的 vector;每一步只根据当前 n 的奇偶决定下一项。
为什么能这样做
因为输出顺序和生成顺序相反,必须先存下来,或者递归/栈式输出。对二级最稳的是 vector。
先避开的坑
题目要求倒序输出,不能按变化过程正序输出。
n=20 的变化过程
演示进度
课堂要求:每一步都让学生说出当前保留了什么信息,以及下一步为什么不会漏答案。
把关键过程写成表
| 当前数 | 规则 | 下一项 |
|---|---|---|
| 20 | 偶数 /2 | 10 |
| 10 | 偶数 /2 | 5 |
| 5 | 奇数 *3+1 | 16 |
| 16 | 偶数 /2 | 8 |
当堂检查
n=5 的下一项是什么?
为什么要用 vector 存序列?
代码读慢一点
#include <bits/stdc++.h>
using namespace std;
int main() {
long long n;
cin >> n;
vector<long long> v;
v.push_back(n);
while (n != 1) {
n = (n % 2) ? n * 3 + 1 : n / 2;
v.push_back(n);
}
for (int i = (int)v.size() - 1; i >= 0; i--) {
cout << v[i] << " \n"[i == 0];
}
return 0;
}
读代码抓这几处
- 先把初始 n 放入 vector。
- while (n != 1) 中更新并保存下一项。
- 最后从 v.size()-1 倒着输出。
复杂度与常见错误
复杂度:时间和空间都与序列长度成正比。
- 忘记保存初始 n。
- 正序输出。
- 奇偶规则写反。
源文件:GESP2/P5727.md · GESP2/P5727_solution.md