入门 · 循环
倒着数
你写过的每个循环都从 1 开始往上走。没有任何规则要求这样:起点、条件、步进是三个独立的选择,而这道题改掉了其中两个。
一句话答案<code>for (int i = n; i >= 1; i--)</code> 逐个打印 i,单个空格分隔,末尾换行。
题目
输入: 一个整数 n(1 ≤ n ≤ 100)。
输出: 从 n 到 1,单个空格分隔,输出在一行。
样例:
| 输入 | 输出 |
|---|---|
5 | 5 4 3 2 1 |
1 | 1 |
n = 1 那个样例很重要:循环恰好只跑一次,任何分隔符逻辑都不可能出错。如果它挂了,bug 在循环边界,不在空格。
你的解答
「运行我的输入」用的自定义输入
判题在浏览器本地运行。死循环会在 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;
}