P1553 数字反转(升级版)

题目背景

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

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

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

题目描述

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

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

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

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

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

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

输入格式

一个实数 sss

输出格式

一个实数,即 sss 的反转数

输入输出样例 #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%25\%25% 的数据,sss 是整数,不大于 202020 位;
  • 对于 25%25\%25% 的数据,sss 是小数,整数部分和小数部分均不大于 101010 位;
  • 对于 25%25\%25% 的数据,sss 是分数,分子和分母均不大于 101010 位;
  • 对于 25%25\%25% 的数据,sss 是百分数,分子不大于 191919 位。

【数据保证】

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

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

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

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

数据不存在负数。

//1553-2
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

string intPart(string s) 
{
    reverse(s.begin(), s.end());
    int start = 0;
    while (start < s.size() && s[start] == '0')     
	  start++;    
    if (start == s.size()) 
        return "0";    
    return s.substr(start);
}

string decPart(string s) 
{
    reverse(s.begin(), s.end());
    int start = 0;
    while (start < s.size() && s[start] == '0') 
        start++;    
    string s1;
    if (start == s.size())      
		 s1 = "0";
    else 
        s1 = s.substr(start);    
    int end = s1.size();
    
    while (end > 0 && s1[end - 1] == '0') 
        end--;  
		  
    if (end == 0) 
        return "0";
    else 
        return s1.substr(0, end);
    
}

int main() {
    string s;
    cin >> s;

    if (s.find('/') != string::npos) 
	{
        int symPos = s.find('/');
        string zhengShu = s.substr(0, symPos);
        string xiaoShu = s.substr(symPos + 1);
        string revNum = intPart(zhengShu);
        string revDen = decPart(xiaoShu);
        cout << revNum << "/" << revDen << endl;
    }
	else if (s.find('.') != string::npos) 
	{
        int dotPos = s.find('.');
        string int_part = s.substr(0, dotPos);
        string dec_part = s.substr(dotPos + 1);
        string revInt = intPart(int_part);
        string revDec = decPart(dec_part);
        cout << revInt << "." << revDec << endl;
    }
	else if (!s.empty() && s.back() == '%')
	{
        string num = s.substr(0, s.size() - 1);
        string revNum = intPart(num);
        cout << revNum << "%" << endl;
    } 
	else
	{
        string rev = intPart(s);
        cout << rev << endl;
    }

    return 0;
}

上面这段代码太复杂了,写了两个函数,一个去前导0,一个去后导0,其实可以在一个函数里面就实现两边都去。现实情况是不可能两边都有,但一个函数就是更方便。

上代码

#include<cstdio>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string s;
string ddStr(string& x)
{
	reverse(x.begin(),x.end());
	int start=0;
	while(x[start]=='0') start++;
	if(start==x.size())  return "0";
	x=x.substr(start);
	int end=x.size();
	while((end-1)>0 && x[end-1]=='0') end--;
	if(end==0) return "0";
	x= x.substr(0,end);
	return x;
}

int main()
{
	cin>>s;
	int symPos;
	//cout<<ddStr(s)<<endl; 
	if(s.find('/')!=-1)
	{
		symPos=s.find('/');	
		string s1=s.substr(0,symPos);
		string s2=s.substr(symPos+1);	
		cout<<ddStr(s1)<<"/"<<ddStr(s2)<<endl; 
	}
	else if(s.find('.')!=-1)
	{
		symPos=s.find('.');	
		string s1=s.substr(0,symPos);
		string s2=s.substr(symPos+1);	
		cout<<ddStr(s1)<<"."<<ddStr(s2)<<endl;; 
	}
	else if(s.back()=='%'&& s.size()>1)
	{
		string s1=s.substr(0,s.size()-1);
		cout<<ddStr(s1)<<"%"<<endl;
	}
	else
		cout<<ddStr(s)<<endl;
	return 0;	
}
Logo

集算法之大成!助力oier实现梦想!

更多推荐