题解:洛谷 P5705 数字反转
【题目来源】
【题目描述】
输入一个不小于 \(100\) 且小于 \(1000\),同时包括小数点后一位的一个浮点数,例如 \(123.4\) ,要求把这个数字翻转过来,变成 \(4.321\) 并输出。
【输入】
一行一个浮点数
【输出】
一行一个浮点数
【输入样例】
123.4
【输出样例】
4.321
【核心思想】
-
问题分析:输入一个范围在 \([100, 1000)\) 且带一位小数的浮点数(如 \(123.4\)),要求将其数字顺序完全反转(如变为 \(4.321\))。这是一个数位拆分与重组问题。
-
算法选择:
- 放大转整法:将浮点数乘以 \(10\) 转为整数,消除小数点,然后逐位拆分、逆序重组,最后除以 \(1000\) 还原为浮点数
-
关键步骤:
- 读入数据:
cin >> t读取浮点数 - 放大转整:
s1 = t * 10,将原数变为整数(如 \(123.4 \to 1234\)) - 逐位拆分:
ge = s1 % 10:个位(原数的小数部分,如 \(4\))shi = s1 / 10 % 10:十位(原数的个位,如 \(3\))bai = s1 / 100 % 10:百位(原数的十位,如 \(2\))qian = s1 / 1000 % 10:千位(原数的百位,如 \(1\))
- 逆序重组:
s2 = ge * 1000 + shi * 100 + bai * 10 + qian(如 \(4 \times 1000 + 3 \times 100 + 2 \times 10 + 1 = 4321\)) - 还原浮点:
ans = s2 / 1000.0(如 \(4321 \to 4.321\)) - 输出结果:
cout << ans
- 读入数据:
-
时间/空间复杂度:
- 时间复杂度:\(O(1)\),固定次数的算术运算
- 空间复杂度:\(O(1)\),仅需常数个变量
-
数位操作的核心思想:
- 消除小数点:乘以 \(10\) 将浮点问题转化为整数问题,避免浮点精度误差
- 模运算取位:
% 10取最低位,/ 10右移一位,配合实现逐位拆分 - 位权重组:逆序后的各位按新的位权(千、百、十、个)组合成新整数
- 精度还原:除以 \(1000.0\)(注意浮点除法)将整数还原为三位小数的浮点数
- 适用于数字反转、数位重组、浮点精度处理类入门问题
【算法标签】
入门 #模拟
【代码详解】
#include <bits/stdc++.h> // 包含标准库头文件(万能头文件)
using namespace std; // 使用标准命名空间
/**
* 主函数 - 程序入口
* @return 程序执行状态码(0表示成功)
*/
int main()
{
double t, ans; // 定义双精度浮点数变量:原始值t,结果ans
int s1, s2; // 定义整型变量:中间值s1,重组值s2
int ge, shi, bai, qian; // 定义各位数字变量:个、十、百、千位
cin >> t; // 从标准输入读取原始数值t
// 数值转换处理
s1 = t * 10; // 将输入值放大10倍转为整数(保留1位小数精度)
// 分解各位数字
ge = s1 % 10; // 获取个位数(原数第1位小数)
shi = s1 / 10 % 10; // 获取十位数(原数个位)
bai = s1 / 100 % 10; // 获取百位数(原数十位)
qian = s1 / 1000 % 10;// 获取千位数(原数百位)
// 数字重组(逆序排列)
s2 = ge * 1000 + shi * 100 + bai * 10 + qian; // 将各位数字按新顺序组合
// 结果处理
ans = s2 / 1000.0; // 将重组后的数缩小1000倍转为浮点数(保留3位小数)
cout << ans; // 输出最终结果
return 0; // 返回程序执行成功状态码
}
【运行结果】
123.4
4.321
浙公网安备 33010602011771号