zoukankan      html  css  js  c++  java
  • 洛谷P1553 数字翻转(升级版)

    洛谷P1553 数字翻转(升级版)

    题目链接

    https://www.luogu.org/problemnew/show/P1553


    题目描述

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

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


    输入输出格式

    输入格式:

    一个数s

    输出格式:

    一个数,即s的反转数


    思路 

    (因为它最多可能很多位数而且有符号所以就用字符串啦)

    1、首先我们定义一个字符串,再定义一个flag标记(this sign is very important!)

    2、读入字符串(不知道getline的看这里,不会的话用cin也可以)//来自cgp大佬的c++字符串详解

    3、从这个首位开始for循环,找到符号的话我们就把flag赋值,下代码中有解析,如果没有符号的话就是纯数字,此时flag的值还是为0,直接反序输出即可

    4、如果flag的值发生改变,就对其进行相应的操作

    5、操作完输出就可以啦!

    (详细的解析见代码)


    上代码

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int A = 505;
    
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
        for( ; isdigit(c); c = getchar()) x = x * 10 +(c ^ 48);
        return x * f;
    }
    
    string s;
    int flag = 0;//标记
    int d; //d这个变量我本想放在if语句中,但是发现编译不过,就放在了外面
    
    int main() {
        getline(cin, s);
        int l = s.length();
        for(int i = 0; i < l; i++) {
            //赋值给d时d的值为i-1是因为s[i]为符号,应该赋值给符号的前一位
            //而这个数是百分数时不赋值是因为百分号肯定是最后一位,不用分开处理
            if(s[i] == '/') { flag = 1; d = i - 1; break; }
            if(s[i] == '%') { flag = 2; break; }
            if(s[i] == '.') { flag = 3; d = i - 1; break;}
        }
        if(flag == 1) { //是分数的情况 
            int len = d + 1;
            //这是为了分成两段处理而定义的len
            //因为d的值可能会发生改变,所以用len代表d的下一位,也就是这个符号——‘/’
            while(s[d] == '0') d--;//去除前导零
            if(d < 0) cout << '0';
            //如果前半段都是0的话,d的值就会变成-1,这时我们要输出‘0’,自然下面这一步就不会执行了,没有影响
            for(int i = d; i >= 0; i--) cout << s[i]; //倒着输出来
            printf("/");//中间的字符
            while(s[l - 1] == '0') l--;//去除前导零
            //因为后半段是分母,题目中说分母不会为0,所以不用特判这里啦!
            for(int i = l - 1; i > len; i--) cout << s[i];//倒着输出来
            return 0;//程序直接结束
        }//是分数的话处理不是很难,也不是很简单,因为它的分母不是0,也不用约分,所以并不是很难
        if(flag == 2)//是百分数的情况 
        {
            int len = s.length() - 2;
            //这里的len为字符串长度减2是因为还有一个符号是百分号
            while(s[len] == '0') len--;//去除前导零
            if(len < 0) cout << '0';//如果都是0的话,len的值就会变成-1,输出‘0’,下面这一步就不再执行,没有影响
            for(int i = len; i >= 0; i--) cout << s[i]; //倒着输出来......
            cout<<'%';//最后输出百分号
            return 0;//程序直接结束
        }//百分数的处理方式很简单,就把它当成数字倒序输出来,再输出一个百分号就可以啦
        if(flag == 3)//是小数的情况 
        {
            int len = d+1;//同flag=1的情况
            while(s[d] == '0') d--;//删前导零
            if(d < 0) cout << '0';//同flag=1的情况
            for(int i = d; i >= 0; i--) cout << s[i];//倒着输出前半段
            printf(".");//中间的字符
            while(s[l] == '0') l--;//删前导零
            len++;//如果不加1就变成判断字符,下面的while语句直接不执行
            while(s[len] == '0') len++;//删除小数后面的零
            len--;//len--,为了进行比较
            if(l - 1 == len) cout << '0';//如果len和l-1的值相等了,说明小数点右边都是零,直接输出0
            for(int i = l - 1; i > len; i--) cout << s[i];//把它输出来
            return 0;//结束程序
        }//自认为是最难的情况,因为整数部分和小数部分都要处理和特判0的情况,而且小数部分最后还不能是零
        if(flag==0) {
            int len = s.length() - 1;
            while(s[len] == '0') len--;
            for(int i = len; i >= 0; i--) cout << s[i];
            if(len<0) cout << '0';
            return 0;
        }//自认为最简单的一种情况,就不说了
    }
  • 相关阅读:
    使用PowerDesigner 15对现有数据库进行生成图表结构
    dynamic的使用
    js 字符串的replace() 方法和实现replaceAll() 方法
    学习新属性 requestAnimationFrame
    Mapbox 地图样式规范
    Emmet插件使用方法总结
    js循环遍历性能
    lunix部署其前端项目常见报错
    componentWillMount和componentDidMount的区别
    控制浏览器禁止缓存
  • 原文地址:https://www.cnblogs.com/loceaner/p/loceaner_p1553.html
Copyright © 2011-2022 走看看