P1553 数字反转(升级版)
题目描述
给定一个数,请将该数各个位上数字反转得到一个新数。
这次与NOIp2011普及组第一题不同的是:这个数可以是小数,分数,百分数,整数。整数反转是将所有数位对调;小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分;分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母;百分数的分子一定是整数,百分数只改变数字部分。整数新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零;小数新数的末尾不为0(除非小数部分除了0没有别的数,那么只保留1个0);分数不约分,分子和分母都不是小数(约分滴童鞋抱歉了,不能过哦。输入数据保证分母不为0),本次没有负数。
输入格式
一个数s
输出格式
一个数,即s的反转数
输入输出样例
输入 #1
5087462
输出 #1
2647805
输入 #2
600.084
输出 #2
6.48
输入 #3
700/27
输出 #3
7/72
输入 #4
8670%
输出 #4
768%
说明/提示
所有数据:25%s是整数,不大于20位
25%s是小数,整数部分和小数部分均不大于10位
25%s是分数,分子和分母均不大于10位
25%s是百分数,分子不大于19位
(20个数据)
首先,我们看到这个题,易分析出这个题有四个步骤:拆分,翻转,去零,输出。
所以我们只要分开编出几个函数进行这几个操作即可。
经过观察,易发现:小数的小数部分需要去除的是后部的零,而其他的需要去除的是前部的零。
不多说了,直接上程序:(用的是对字符串的处理)(程序有点长,但思路非常简单易懂)
1 #include<bits/stdc++.h> 2 #include <cstring> 3 using namespace std; 4 string qutou(string a)//作用:去除头部的零 5 { 6 int len; 7 while(a[0]=='0'&&len!=1)//如果第一位还是零 8 { 9 len=a.size(); 10 a=a.substr(1,len-1);//把除了第一位之外的部分向前移动一位,覆盖第一位的零 11 } 12 return a; 13 } 14 string quwei(string a)//作用:去除头部的零 15 { 16 int len=a.size(); 17 while(a[len-1]=='0')//如果第一位还是零 18 { 19 a=a.substr(0,len-1 );//把除了最后一位之外的部分向后移动一位,覆盖最后一位的零 20 len--; 21 } 22 return a; 23 } 24 string fanzhuan(string a)//作用:将数翻转 25 { 26 int len=a.size(); 27 string b;//创建一个临时字符串"b" 28 for(int i=len-1;i>=0;i--)//将a反向粘贴到b上 29 { 30 b+=a[i]; 31 } 32 return b;//返回b 33 } 34 int main() 35 { 36 string front,behind,total;//字符串front,behind分别用来储存小数和分数的前半部分和后半部分 37 getline(cin,total); 38 int len=total.size(),n=0,form=0; 39 for(int i=0;;i++)//遍历字符串 40 { 41 if(total[i]!='/'&&total[i]!='%'&&total[i]!='.')//如果当前位置不是特殊字符 42 { 43 front+=total[i];//将这个字符储存进front中 44 } 45 if(total[i]=='/')//如果是'/',说明分子已经读入结束 46 { 47 form=1;//记录下这个数是分数 48 n=i+1; 49 break;//结束读取分子 50 } 51 if(total[i]=='%')//如果是'%',说明百分数已经读入结束 52 { 53 form=2;//记录下这个数是百分数 54 break;//结束读取 55 } 56 if(total[i]=='.')//如果是'.',说明整数部分已经读入结束 57 { 58 form=3;//记录下这个数是小数 59 n=i+1; 60 break;//结束读取整数部分 61 } 62 if(i==len-1)//如果一直读取到了最后一位还没有特殊符号 63 { 64 form=4;//记录下这个数是整数 65 break;//结束读取 66 } 67 } 68 if(form==1||form==3)//如果是分数或小数 69 { 70 for(int j=n;j<=len-1;j++)//读取分母(或小数部分) 71 { 72 behind+=total[j]; 73 } 74 behind=fanzhuan(behind);//翻转后部 75 } 76 front=fanzhuan(front);//翻转前部 77 front=qutou(front);//对前部进行去除头部的零 78 if(form==1)//如果是分数 79 { 80 behind=qutou(behind);//对后部进行去除头部的零 81 if(front=="\0")//如果前部去头之后什么也不剩,说明前部是零 82 { 83 cout<<"0/"<<behind; 84 } 85 else 86 { 87 cout<<front<<"/"<<behind;//输出 88 } 89 } 90 if(form==2)//如果是百分数 91 { 92 front=qutou(front); 93 if(front=="\0")//如果前部去头之后什么也不剩,说明前部是零 94 { 95 cout<<"0%"; 96 } 97 else 98 { 99 cout<<front<<"%";//输出 100 } 101 } 102 if(form==3)//如果是分数 103 { 104 behind=quwei(behind);//对后部进行去除尾部的零 105 if(behind=="\0") 106 { 107 if(front=="\0")//如果前部去头之后什么也不剩,说明前部是零 108 { 109 front="0"; 110 } 111 cout<<front<<".0"; 112 } 113 else 114 { 115 cout<<front<<"."<<behind;//输出 116 } 117 } 118 if(form==4)//如果是整数 119 { 120 front=qutou(front); 121 if(front=="\0")//如果前部去头之后什么也不剩,说明前部是零 122 { 123 cout<<"0"; 124 } 125 else 126 { 127 cout<<front;//输出 128 } 129 } 130 return 0; 131 }