数字反转(升级版)
题目背景
给定一个数,请将该数各个位上数字反转得到一个新数。
这个数可以是小数,分数,百分数,整数。整数反转是将所有数位对调;小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分;分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母;百分数的分子一定是整数,百分数只改变数字部分。整数新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零;小数新数的末尾不为0(除非小数部分除了0没有别的数,那么只保留1个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%
数据保证:
- 对于整数翻转而言,整数原数和整数新数满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数和原来的数字的最高位数字不应为零。
- 对于小数翻转而言,其小数点前面部分同上,小数点后面部分的形式,保证满足小数的常见形式,也就是末尾没有多余的 $0$(小数部分除了 $0$ 没有别的数,那么只保留 $1$ 个 $0$。若反转之后末尾数字出现 $0$,请省略多余的 $0$)
- 对于分数翻转而言,分数不约分,分子和分母都不是小数。输入的分母不为 $0$。与整数翻转相关规定见上。
- 对于百分数翻转而言,见与整数翻转相关内容。
- 数据不存在负数。
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
getline(cin,s);
if(s[0]=='0'&&s.length()==1){
cout<<'0';
return 0;
}
int i=0;
for(;i<s.length();i++){
if(s[i]>='0'&&s[i]<='9'){}
else if(s[i]=='.'){
int ret=0;
for(int j=i-1;j>=0;j--){
if((i-1)==0)cout<<s[0];
else{if(s[j]=='0'&&ret)cout<<s[j];
else if(s[j]!='0'){
cout<<s[j];
ret=1;
}
}
}
cout<<'.';
ret=0;
i++;
while(s[i]=='0'&&i<s.length())i++;
if(i==s.length())cout<<'0';
else{
for(int j=s.length()-1;j>=i;j--)cout<<s[j];
break;
}
}
else if(s[i]=='/'){
int ret=0;
for(int j=i-1;j>=0;j--){
if((i-1)==0)cout<<'0';
else{if(s[j]=='0'&&ret)cout<<s[j];
else if(s[j]!='0'){
cout<<s[j];
ret=1;
}
}
}
cout<<'/';
ret=0;
for(int j=s.length()-1;j>i;j--){
if(s[j]=='0'&&ret)cout<<s[j];
else if(s[j]!='0'){
cout<<s[j];
ret=1;
}
}
break;
}
else if(s[i]=='%'){
int ret=0;
if(s[0]=='0')cout<<'0';
else{
for(int j=s.length()-2;j>=0;j--){
if(s[j]=='0'&&ret)cout<<s[j];
else if(s[j]!='0'){
cout<<s[j];
ret=1;
}
}
}
cout<<"%";
break;
}
}
if(i==s.length()){
int ret=0;
for(int j=s.length()-1;j>=0;j--){
if(s[j]=='0'&&ret)cout<<s[j];
else if(s[j]!='0'){
cout<<s[j];
ret=1;
}
}
}
}
思路:
1.整数情况:正常整数只要考虑除0就行,方法是ret开关,碰到非0数后ret开启即可输出0,否则一直不输出;特殊情况1:就只有0,单独讨论输出即可;
2.小数情况:正常情况下,遇到小数点前倒序输出,小数点后倒序输出即可,注意整数部分除0,小数部分情况复杂,特殊情况1:小数部分以0开始,即:0.004这种,采用移动i到非零位即可;特殊情况2:小数部分只有0,即:13.0这种,属于第一种的特殊情况,遍历完如果i>s.length(),则证明全是0,输出一个0即可;特殊情况3:小数部分最后有0,即:14.0030这种,处理方法更简单,不管是否为0输出即可;
3.分数情况:正常情况下相当于两个整数,分别倒序即可,注意除0,特殊情况1:分子为0,单独讨论输出即可;
4.百分数情况:即整数+'%',类似于整数,只需改变部分细节即可。
注意:
1.题目难度在处理各种各样的0上,需要判断多种特殊情况。