入门 · 判断
绝对值
绝对值扔掉符号、留下大小。数本身非负就什么都不用做;是负数就翻过来。两种情况,一个分岔 —— 而零必须落在正确的那一边。
一句话答案若 <code>n < 0</code> 就输出 <code>-n</code>,否则输出 <code>n</code>。
题目
输入: 一个整数 n(−1000000 ≤ n ≤ 1000000)。
输出: n 的绝对值。
样例:
| 输入 | 输出 |
|---|---|
-7 | 7 |
3 | 3 |
零是真正的边界情况:它的绝对值是 0,不是 −0。条件写成 n < 0(而不是 n <= 0),零就自动落在无害的那一边。
你的解答
「运行我的输入」用的自定义输入
判题在浏览器本地运行。死循环会在 3 秒后被自动中断 —— 但还是确保每个循环都有出口。代码随打随存。
卡住了?提示
提示 1 — 两种情况,不是三种
正数和零的处理一样(原样打印),所以它们合成一个分支。只有负数是特殊的。写三个分支是新手的常见直觉,而且永远多了一个。
提示 2 — 取负就是从零里减
-n 产生相反的值,而不改动 n 本身。想写得更显式,0 - n 是同一件事。两种写法都直接打印结果 —— 别先存回去再打印,那只是多几行。
提示 3 — 为什么不直接调 abs()
可以 —— <cstdlib> 里的 abs() 在这里能用。但这道题要练的是分岔,亲手写一次,那个三行的库函数就不再是魔法。两种都试试,确认结果一致。
题解(先自己试试!)
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
if (n < 0) {
cout << -n << endl;
} else {
cout << n << endl;
}
return 0;
}
符号处理到处都有:奇偶统计 里的负余数、整数除法那篇里的负数除法、日期相差几天 里的负数距离。早点对负数分支熟悉起来,后面处处省事。
深度解析
为什么这样做对
绝对值是分两种情况定义的:非负数自己就是自己的大小,负数需要翻符号。只有负数那一支需要分岔,而 -n 能算出翻转结果,又不改动 n 本身。
代价
O(1) —— 一次比较、一次取负。
常见错法
- 把
n < 0写成n <= 0。零照样输出 0,但这个分支现在宣称「零是负数」—— 以后一旦为每支加逻辑,零就落错边了。 - 写
n = -n然后在两支里各打印一次,输出重复。在末尾打印一次就好。 - 以为答案一定装得进
int—— 这里可以,因为输入范围对称。对-2147483648就不行,这就是经典的abs(INT_MIN)溢出。
下一步
一旦涉及余数,符号处理就更微妙:奇偶统计 和 整数除法那篇。
记住这两句
- 两种情况就够:负数翻转,其余不动。
- 用
n < 0而不是n <= 0,让零留在无害的那边。
🐞 这段是错的 —— 点开,亲手让它挂一次
只处理了负数分支 —— 非负输入什么都不打印
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
if (n < 0) {
cout << -n << endl;
}
// bug: no else branch, so 0 and positives print nothing
return 0;
}