入门 · 循环

倒着数

你写过的每个循环都从 1 开始往上走。没有任何规则要求这样:起点、条件、步进是三个独立的选择,而这道题改掉了其中两个。

一句话答案<code>for (int i = n; i &gt;= 1; i--)</code> 逐个打印 i,单个空格分隔,末尾换行。

题目

输入: 一个整数 n(1 ≤ n ≤ 100)。

输出: 从 n 到 1,单个空格分隔,输出在一行。

样例:

输入输出
55 4 3 2 1
11

n = 1 那个样例很重要:循环恰好只跑一次,任何分隔符逻辑都不可能出错。如果它挂了,bug 在循环边界,不在空格。

你的解答

main.cpp — 你的解答
「运行我的输入」用的自定义输入

判题在浏览器本地运行。死循环会在 3 秒后被自动中断 —— 但还是确保每个循环都有出口。代码随打随存。

卡住了?提示

提示 1 — 把三部分翻过来

向上数是 i = 1; i <= n; i++。向下数是 i = n; i >= 1; i-- —— 从高处起、只要还大于等于 1 就继续、每步减一。两处改动:比较方向和步进符号。必须一起改,否则循环永不结束。

提示 2 — 空格在中间,不在末尾

在除第一个外的每个数之前打空格 —— 或者在除最后一个外的每个数之后打空格。两种都行;出问题的是「每个数后面都打空格」,一旦判题对行尾处理不一致就挂。本站会掐掉行尾空格,但这个习惯是对的。

提示 3 — n = 1 的陷阱

n = 1 时循环只跑一次,打印一个数,完全没有分隔符。任何假设「至少两个元素」的分隔逻辑在这里都会崩。相信你的格式之前,先跑一遍第二个样例。

题解(先自己试试!)
#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;

    for (int i = n; i >= 1; i--) {
        cout << i;
        if (i > 1) cout << " ";
    }
    cout << endl;
    return 0;
}

向下数的循环不常见,但总出现在「输出顺序很重要」的地方:反转数字 里倒着取位、括号匹配 里从栈顶往下弹、二进制表示 里把位倒着打。而反向边界正是差一 bug 的高发区。

深度解析

为什么这样做对

for 循环的三部分各自独立:起点、继续条件、步进。倒着数只是改成从高处开始、测 >= 1、用 -- 步进。循环形状完全一样,只是方向翻了。

代价

时间 O(n)、额外空间 O(1) —— n 次迭代,每次一个数字外加可能一个空格。

常见错法

  • 只改了一个:方向改了、步进没改(i = n; i >= 1; i++)会永不终止,因为条件一直为真。
  • 分隔逻辑假设「至少两个元素」。n = 1 时循环只打一个数、完全没有分隔符 —— 跑一下那个样例。
  • i > 0 和 i >= 1 对整数等价,但和 unsigned 类型或浮点步进混用时会引入细微差别。选定一种并一直用。

下一步

反向遍历在「输出顺序很重要」的地方无处不在:反转数字、二进制表示、括号匹配。

记住这两句

  • 起点、条件、步进各自独立 —— for 循环可以朝任一方向走。
  • 方向和步进符号必须一起改,否则循环永不结束。
🐞 这段是错的 —— 点开,亲手让它挂一次

数到 2 就停了 —— 条件本应让 1 也通过

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    for (int i = n; i > 1; i--) {   // bug: drops the final 1
        cout << i << " ";
    }
    cout << endl;
    return 0;
}