【深基5.例3】冰雹猜想

GitHub跳转原题关系图返回列表

按奇偶规则模拟冰雹序列,把经过的数存入列表后反转输出。

OJ: luogu

题目 ID: P5727

难度:入门

标签:模拟列表python

日期: 2026-07-15 18:44

题意

给出正整数 n。不断执行:

  • 如果 n 是奇数,变成 3n + 1
  • 如果 n 是偶数,变成 n / 2

直到变成 1。要求从最后的 1 开始,倒序输出整个变化序列。

思路

先按题意正向模拟,把每次出现的数字加入列表 sequence

n != 1 时继续循环。每轮根据奇偶选择下一步:

text
奇数:n = n * 3 + 1
偶数:n = n // 2

循环结束后,sequence 中保存的是从初始值到 1 的顺序。题目要求倒序输出,所以反转列表后输出即可。

这题是列表保存过程再倒序输出的练习,不创建 brute.py

Python 知识

  • /home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:用 int(input()) 读取单个整数,用 print(*sequence) 输出列表。
  • /home/rainboy/mycode/hugo-blog/content/program_language/python/math_tools.md// 是整数除法,适合偶数除以 2
  • n % 2 == 1 判断奇数。
  • sequence.append(n) 保存过程值,sequence.reverse() 原地反转。

代码

python
n = int(input())

sequence = [n]
while n != 1:
    if n % 2 == 1:
        n = n * 3 + 1
    else:
        n //= 2
    sequence.append(n)

sequence.reverse()
print(*sequence)
cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-07-27 00:00
 * update_at: 2026-07-27 00:00
 */

#include <bits/stdc++.h>
using namespace std;

int a[10005]; // 保存冰雹序列
int cnt;      // 序列长度

int main() {
    int n;
    cin >> n;
    // 先把起始数存入
    a[++cnt] = n;
    // 按规则模拟,直到变成 1
    while (n != 1) {
        if (n % 2 == 1) // 奇数:3n+1
            n = n * 3 + 1;
        else            // 偶数:n/2
            n /= 2;
        a[++cnt] = n;
    }
    // 题目要求倒序输出(从 1 开始)
    for (int i = cnt; i >= 1; i--) cout << a[i] << " ";
    return 0;
}

Pythonic 写法

用条件表达式写奇偶变换,sequence[::-1] 切片反转输出:

python
n = int(input())
sequence = [n]
while n != 1:
    n = n * 3 + 1 if n % 2 else n // 2
    sequence.append(n)
print(*sequence[::-1])

复杂度

设序列长度为 k。模拟和反转都是 O(k)O(k),空间复杂度是 O(k)O(k)

总结

这题不要一边倒序一边输出。先把正向过程存下来,再反转输出,代码更直接,也更容易检查。