题解:洛谷 P1307 数字反转
【题目来源】
洛谷:P1307 [NOIP 2011 普及组] 数字反转 - 洛谷(luogu.com.cn)
【题目描述】
给定一个整数 \(N\),请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例 2)。
【输入】
一个整数 \(N\)。
【输出】
一个整数,表示反转后的新数。
【输入样例】
123
【输出样例】
321
【核心思想】
-
问题分析:给定整数 \(N\),将其各位数字反转得到新数。需处理负数情况和前导零(反转后自动去除,因整数存储不保留前导零)。
-
算法选择:
- 数位剥离重组:逐位取出 \(N\) 的最低位,按反序构建新数
- 负数处理:先标记负数,取绝对值处理,最后恢复符号
-
关键步骤:
- 读入数据:
cin >> n - 处理负数:
- 若
n < 0:mark = true,n = -n(转为正数)
- 若
- 反转循环(当
n != 0):t = n % 10:取最低位n /= 10:去掉最低位s = s * 10 + t:将取出的位添加到结果末尾(实现反转)
- 恢复符号:若
mark为真,s = -s - 输出结果:
s
- 读入数据:
-
时间/空间复杂度:
- 时间复杂度:\(O(\log_{10} |N|)\),与数字位数成正比
- 空间复杂度:\(O(1)\),仅需常数个变量
-
数位反转的核心思想:
- 乘十进位:
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
浙公网安备 33010602011771号