P1553 数字反转(升级版)

1.题目介绍

数字反转(升级版)

题目背景

以下为原题面,仅供参考:

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

这次与 NOIp2011 普及组第一题不同的是:这个数可以是小数,分数,百分数,整数。整数反转是将所有数位对调;小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分;分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母;百分数的分子一定是整数,百分数只改变数字部分。整数新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零;小数新数的末尾不为 0(除非小数部分除了 0 没有别的数,那么只保留1个 0);分数不约分,分子和分母都不是小数(约分滴童鞋抱歉了,不能过哦。输入数据保证分母不为 0),本次没有负数。

题目描述

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

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

  • 整数反转是将所有数位对调。

  • 小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分。

  • 分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母。

  • 百分数的分子一定是整数,百分数只改变数字部分。

输入格式

一个实数 s

输出格式

一个实数,即 s 的反转数

样例 #1

样例输入 #1

5087462

样例输出 #1

2647805

样例 #2

样例输入 #2

600.084

样例输出 #2

6.48

样例 #3

样例输入 #3

700/27

样例输出 #3

7/72

样例 #4

样例输入 #4

8670%

样例输出 #4

768%

提示

【数据范围】

  • 对于 25% 的数据,s 是整数,不大于 20 位;
  • 对于 25% 的数据,s 是小数,整数部分和小数部分均不大于 10 位;
  • 对于 25% 的数据,s 是分数,分子和分母均不大于 10 位;
  • 对于 25% 的数据,s 是百分数,分子不大于 19 位。

【数据保证】

  • 对于整数翻转而言,整数原数和整数新数满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数和原来的数字的最高位数字不应为零。

  • 对于小数翻转而言,其小数点前面部分同上,小数点后面部分的形式,保证满足小数的常见形式,也就是末尾没有多余的 0(小数部分除了 0 没有别的数,那么只保留 10。若反转之后末尾数字出现 0,请省略多余的 0

  • 对于分数翻转而言,分数不约分,分子和分母都不是小数。输入的分母不为 0。与整数翻转相关规定见上。

  • 对于百分数翻转而言,见与整数翻转相关内容。

数据不存在负数。

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已经不满足了 
	}
}
posted @   DawnTraveler  阅读(80)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示