进阶 · 数位

回文数

一个数倒着读和正着读一样,就是回文数:121 是,123 不是。如果你做过反转数字,整个算法你已经有了 — 这道题考的是认出来。

一句话答案把数字反转后和原数比较:相等就输出 palindrome,否则 not a palindrome,不需要转成字符串。

题目

输入: 一个正整数 N(1 ≤ N ≤ 10⁹)。

输出: 倒读相同输出 palindrome,否则 not a palindrome(一字不差)。

样例:

输入输出
121palindrome
10not a palindrome

你的解答

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

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

卡住了?提示

提示 1 — 一个大坑:循环会吃掉输入

反转循环一路 n /= 10 到零。要和原值比,所以先存一份:int orig = n;。忘了拷贝是这道题的头号 bug。

提示 2 — 一位数

7 反转还是 7 — 每个一位数自动是回文数,"反转再比较"不需要任何特判就能处理它。如果你的代码要写 if (n < 10),那是过度设计了。

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

int main() {
    int n;
    cin >> n;
    int orig = n;
    int rev = 0;
    while (n > 0) {
        rev = rev * 10 + n % 10;
        n /= 10;
    }
    if (rev == orig) cout << "palindrome" << endl;
    else cout << "not a palindrome" << endl;
    return 0;
}

至此拆位工具箱集齐:数、加、反、比。整个题解只比上一题多两行新代码 — 模式复用才是这道题的真功课。下一题:用星号金字塔玩形状。

深度解析

为什么这样做对

会反转之后,回文就是「反转 + 比较」。这题的考点是识别复用,而不是再写一套新代码。

代价

O(d);如果从两头往中间走,可以只做一半。

常见错法

  • 负数永远不是回文(负号),但 -121 数值反转回来还是 -121。写代码前先把负数这一支定死。
  • 真编译器里 to_string 是最省事的路,但本站引擎没有 std::string——能跑的是数值解法。

下一步

同样的对称问题换到文本上:反转字符串。

记住这两句

  • 新题常常是老题加一次比较。
  • 负数在算法之前处理,不要在算法之后补。
🐞 这段是错的 —— 点开,亲手让它挂一次

拿 n 去比,可循环已经把它清成 0 了

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int rev = 0, m = n;
    while (m > 0) {
        rev = rev * 10 + m % 10;
        m /= 10;
    }
    if (n == rev) cout << "yes" << endl;
    else cout << "no" << endl;
    return 0;
}