P1553 数字反转(升级版)
1.题目介绍
数字反转(升级版)
题目背景
以下为原题面,仅供参考:
给定一个数,请将该数各个位上数字反转得到一个新数。
这次与 NOIp2011 普及组第一题不同的是:这个数可以是小数,分数,百分数,整数。整数反转是将所有数位对调;小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分;分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母;百分数的分子一定是整数,百分数只改变数字部分。整数新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零;小数新数的末尾不为
题目描述
给定一个数,请将该数各个位上数字反转得到一个新数。
这次与 NOIp2011 普及组第一题不同的是:这个数可以是小数,分数,百分数,整数。
-
整数反转是将所有数位对调。
-
小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分。
-
分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母。
-
百分数的分子一定是整数,百分数只改变数字部分。
输入格式
一个实数
输出格式
一个实数,即
样例 #1
样例输入 #1
5087462
样例输出 #1
2647805
样例 #2
样例输入 #2
600.084
样例输出 #2
6.48
样例 #3
样例输入 #3
700/27
样例输出 #3
7/72
样例 #4
样例输入 #4
8670%
样例输出 #4
768%
提示
【数据范围】
- 对于
的数据, 是整数,不大于 位; - 对于
的数据, 是小数,整数部分和小数部分均不大于 位; - 对于
的数据, 是分数,分子和分母均不大于 位; - 对于
的数据, 是百分数,分子不大于 位。
【数据保证】
-
对于整数翻转而言,整数原数和整数新数满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数和原来的数字的最高位数字不应为零。
-
对于小数翻转而言,其小数点前面部分同上,小数点后面部分的形式,保证满足小数的常见形式,也就是末尾没有多余的
(小数部分除了 没有别的数,那么只保留 个 。若反转之后末尾数字出现 ,请省略多余的 ) -
对于分数翻转而言,分数不约分,分子和分母都不是小数。输入的分母不为
。与整数翻转相关规定见上。 -
对于百分数翻转而言,见与整数翻转相关内容。
数据不存在负数。
2.题解
2.1 字符串函数
思路
这里问题主要是去除前导0和后导0的问题,后导0应只存在于小数部分中(毕竟只有小数部分可以以0开头)
个人觉得我的做法比较独特的点就是利用stoi和stol函数去除前导0,因为对于字符串048之类的,经stoi或stol转换后都会变成48,这样就很好的去除了前导0
后导0在小数部分单独讨论一下处理方法即可。
这里还利用到了一些字符串函数,比如像string::find. string::find_first_not_of(找到第一个不位字符串...和...和...的位置pos,对应的函数find_last_not_of时找最后一个的), std::reverse(字符串翻转函数)
还要注意这里的范围,stoi无法处理二十位的数据!!!
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
string str;
getline(cin, str);
int n = str.length();
int pos = 0;
//1.处理小数部分
if((pos = str.find(".")) != -1){
string left = str.substr(0, pos);
int rpos = str.find_first_not_of("0", pos + 1); // 找到小数部分第一个不为0的数,翻转(去除尾部 0)
//1.若小数部分只有一个0
if (rpos == -1) {
reverse(left.begin(), left.end());
cout << stoi(left) << '.' << 0; //使用stoi的方式去除头部0,(像是字符串0048, stoi后会变为48)
}
//2.若小数部分不止一个0
else{
string right = str.substr(rpos);
reverse(left.begin(), left.end());
reverse(right.begin(), right.end());
cout << stoi(left) << '.' << stoi(right); //使用stoi的方式去除头部0
}
}
//2.处理分数部分
else if((pos = str.find("/")) != -1){
string left = str.substr(0, pos);
string right = str.substr(pos + 1);
reverse(left.begin(), left.end());
reverse(right.begin(), right.end());
cout << stoi(left) << '/' << stoi(right); //使用stoi的方式去除头部0
}
//3.处理百分数部分
else if((pos = str.find("%")) != -1){
string temp = str.substr(0, str.length() - 1);
reverse(temp.begin(), temp.end());
cout << stol(temp) << '%'; //使用stol的方式去除头部 0, 注意这里题目说不多于20位!!! stoi已经不满足了
}
//4.处理整数部分
else{
reverse(str.begin(), str.end());
cout << stol(str); //使用stol的方式去除头部 0, 注意这里题目说不多于20位!!! stoi已经不满足了
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了