题解:洛谷 P1553 数字反转(升级版)

【题目来源】

洛谷:P1553 数字反转(升级版) - 洛谷

【题目描述】

给定一个数,请将该数各个位上数字反转得到一个新数。

这次与 NOIP2011 普及组第一题不同的是:这个数可以是小数,分数,百分数,整数。

  • 整数反转是将所有数位对调。
  • 小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分。
  • 分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母。
  • 百分数的分子一定是整数,百分数只改变数字部分。

【输入】

一个实数 \(s\)

【输出】

一个实数,即 \(s\) 的反转数

【输入样例】

700/27

【输出样例】

7/72

【算法标签】

《洛谷 P1553 数字反转(升级版)》 #模拟# #字符串# #洛谷原创#

【代码详解】

#include <bits/stdc++.h>  // 包含标准库头文件(万能头文件)
using namespace std;      // 使用标准命名空间

/**
 * 翻转整数部分
 * @param s 要翻转的数字字符串
 */
void f0(string s) 
{
    int len = s.length();  // 获取字符串长度
    int mark;              // 标记第一个非零字符的位置
  
    // 从后往前找到第一个非零字符
    for (mark = len - 1; mark >= 0; mark--) 
    {
        if (s[mark] != '0') 
            break;
    }
  
    // 如果全是零,输出0并返回
    if (mark < 0) 
    {
        cout << 0;
        return;
    }
  
    // 从第一个非零字符开始倒序输出
    for (int i = mark; i >= 0; i--) 
    {
        cout << s[i];
    }
}

/**
 * 翻转小数部分
 * @param s 要翻转的小数字符串
 */
void f1(string s) 
{
    int m = s.find(".");            // 找到小数点位置
    int len = s.length();          // 获取字符串长度
    string s1 = s.substr(0, m);    // 提取整数部分
    string s2 = s.substr(m + 1, len - m - 1);  // 提取小数部分
  
    f0(s1);                         // 翻转整数部分
    cout << '.';                    // 输出小数点
  
    // 处理小数部分前导零
    int mark = 0;
    for (mark = 0; mark < s2.length(); mark++) 
    {
        if (s2[mark] != '0') 
            break;
    }
  
    // 如果小数部分全是零,输出0并返回
    if (mark >= s2.length()) 
    {
        cout << 0;
        return;
    }
  
    // 翻转小数部分(去掉末尾的零)
    for (int i = s2.length() - 1; i >= mark; i--) 
    {
        cout << s2[i];
    }
}

/**
 * 翻转分数部分
 * @param s 要翻转的分数字符串
 */
void f2(string s) 
{
    int m = s.find("/");            // 找到分数线位置
    int len = s.length();           // 获取字符串长度
    string s1 = s.substr(0, m);     // 提取分子部分
    string s2 = s.substr(m + 1, len - m - 1);  // 提取分母部分
  
    f0(s1);                         // 翻转分子部分
    cout << '/';                    // 输出分数线
    f0(s2);                         // 翻转分母部分
}

/**
 * 翻转百分数部分
 * @param s 要翻转的百分数字符串
 */
void f3(string s) 
{
    int m = s.find("%");            // 找到百分号位置
    int len = s.length();           // 获取字符串长度
    string s1 = s.substr(0, m);    // 提取数字部分
  
    f0(s1);                         // 翻转数字部分
    cout << '%';                    // 输出百分号
}

int main()
{
    string s;                       // 定义字符串:存储输入的数字
    cin >> s;                       // 输入数字字符串
  
    // 根据数字类型调用对应的处理函数
    if (s.find("/") != -1)          // 如果是分数
    {
        f2(s);
    } 
    else if (s.find("%") != -1)      // 如果是百分数
    {
        f3(s);
    } 
    else if (s.find(".") != -1)     // 如果是小数
    {
        f1(s);
    } 
    else                             // 如果是整数
    {
        f0(s);
    }
  
    return 0;                       // 程序正常结束
}

【运行结果】

700/27
7/72
posted @ 2026-02-16 16:08  团爸讲算法  阅读(2)  评论(0)    收藏  举报