题解:洛谷 P1307 数字反转

【题目来源】

洛谷:P1307 [NOIP 2011 普及组] 数字反转 - 洛谷(luogu.com.cn)

【题目描述】

给定一个整数 \(N\),请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例 2)。

【输入】

一个整数 \(N\)

【输出】

一个整数,表示反转后的新数。

【输入样例】

123

【输出样例】

321

【核心思想】

  1. 问题分析:给定整数 \(N\),将其各位数字反转得到新数。需处理负数情况和前导零(反转后自动去除,因整数存储不保留前导零)。

  2. 算法选择

    • 数位剥离重组:逐位取出 \(N\) 的最低位,按反序构建新数
    • 负数处理:先标记负数,取绝对值处理,最后恢复符号
  3. 关键步骤

    • 读入数据cin >> n
    • 处理负数
      • n < 0mark = truen = -n(转为正数)
    • 反转循环(当 n != 0):
      • t = n % 10:取最低位
      • n /= 10:去掉最低位
      • s = s * 10 + t:将取出的位添加到结果末尾(实现反转)
    • 恢复符号:若 mark 为真,s = -s
    • 输出结果s
  4. 时间/空间复杂度

    • 时间复杂度:\(O(\log_{10} |N|)\),与数字位数成正比
    • 空间复杂度:\(O(1)\),仅需常数个变量
  5. 数位反转的核心思想

    • 乘十进位s = s * 10 + t 将已反转的部分左移一位,为新数字腾出个位
    • 模运算取位n % 10 取最低位,n /= 10 右移一位,配合实现从低位到高位的遍历
    • 前导零自动消除:如 \(380\) 反转时依次得到 \(0, 8, 3\),构建过程为 \(0 \to 8 \to 83\),前导零自然消失
    • 符号隔离处理:先转成正数处理,避免负号干扰取模运算,最后恢复符号
    • 适用于数字反转、数位重组、符号处理类入门问题

【算法标签】

入门 #模拟

【代码详解】

#include <bits/stdc++.h>  // 包含标准库头文件
using namespace std;

int main()
{
    int n, s = 0, t;  // n:输入整数, s:反转后的数, t:临时存储数字
    bool mark = false;  // 标记是否为负数

    // 输入整数n
    cin >> n;

    // 处理负数情况
    if (n < 0) {
        mark = true;    // 设置负数标记
        n = -1 * n;     // 转为正数处理
    }

    // 数字反转过程
    while (n != 0) {
        t = n % 10;     // 获取最后一位数字
        n /= 10;        // 去掉最后一位
        s = s * 10 + t; // 将数字添加到反转结果中
    }

    // 如果是负数,恢复负号
    if (mark) {
        s = -1 * s;
    }

    // 输出反转后的数字
    cout << s;

    return 0;
}

【运行结果】

-380
-83
posted @ 2026-08-05 15:44  团爸讲算法  阅读(28)  评论(0)    收藏  举报