Luogu P1553 Digital Flip (Upgraded Edition)

Keywords: C++

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

 

Title Description

 

Given a number, invert the digits on each bit of the number to get a new number.

This time, unlike the first question of the NOIp2011 Popularization Group, this number can be decimal, fractional, percentage and integer. Integer inversion is the reversion of all digits; decimal inversion is the reversion of the integer part, and then the decimal part of the number inversion, do not exchange the integer part and the decimal part; fractional inversion is the reversion of the number of denominators, and then the number of molecules inversion, do not exchange molecules and denominators; percentages of molecules must be integers, percentages only change the digital part. Integer new numbers should also satisfy the common form of integers, that is, unless the given original number is zero, the highest number of new numbers obtained by inversion should not be zero; the end of the new decimal number should not be zero (except that the decimal part has no other number except 0, then only retain 1 0); the fraction is no fraction, the molecular and denominator are not decimal (about the children's shoes, sorry, can not pass oh). Enter data to ensure that the denominator is not zero, there is no negative number this time.

 

Input and Output Format

Input format:

A number s

Output format:

A number, the inversion of s

 

Train of thought:

 

(Because it can be many digits at most and has symbols, it uses strings.)

 

1. First we define a string, and then we define a flag tag (this sign is very important!).

 

2. Read in strings( Look here without knowing getline If not, cin can also be used)// c++ String Details from the cgp Big Man

 

3. Start the for loop from this first place. If we find the symbol, we assign the flag. The next code has parsing. If there is no symbol, it is a pure number. At this time, the value of flag is still 0, so we can output directly in reverse order.

 

4. If the value of flag changes, it should be operated accordingly.

 

5. Output is OK after operation.

 

(See the code for detailed analysis)

 

Upper Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;

string s;
int flag=0;//sign
int d;
//d This variable I wanted to put in if Statement, but found that compiled, but placed outside

int main() {
    getline(cin,s);
    int l=s.length();
    for(int i=0; i<l; i++) {
        //Assign to d time d The value is i-1 Because s[i]For symbols, they should be assigned to the first one of the symbols.
        //And this number is not assigned when it is a percentage because the percentage must be the last one.,No separate treatment
        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)//Score 
    {
        int len=d+1;
        //This is defined to be done in two sections. len
        //because d The value of 0 may change, so use ___________ len representative d Next, that's the symbol.——'/'
        while(s[d]=='0') d--;//Remove leading zeros
        if(d<0)cout<<'0';
        //If the first half is zero, d The value becomes-1,At this point we have to output'0',Naturally, the next step will not be executed, without any impact.
        for(int i=d; i>=0; i--) cout<<s[i];
        //Output backwards
        printf("/");//Characters in the middle
        while(s[l-1]=='0') l--;//Remove leading zeros
        //Because the second half is the denominator, the title said that the denominator will not be 0, so there is no need to judge here!
        for(int i=l-1; i>len; i--) cout<<s[i];
        //Output backwards
        return 0;//Direct termination of the program
    }//It's not very difficult to deal with fractions, nor is it very simple, because its denominator is not zero, nor does it need to be reduced, so it's not very difficult.
    if(flag==2)//It's a percentage case. 
    {
        int len=s.length()-2;
        //There len Reduce the length of the string by 2 because there is another sign that is a percent sign.
        while(s[len]=='0') len--;//Remove leading zeros
        if(len<0)cout<<'0';//If it's all zero, len The value becomes-1,output'0',The next step will not be executed, without any impact.
        for(int i=len; i>=0; i--) cout<<s[i];
        //Output backwards......
        cout<<'%';//Final Output Percentage
        return 0;//Direct termination of the program
    }//Percentage is handled in a simple way. Just output it in reverse order as a number, and then output a percentage number.
    if(flag==3)//In the case of decimal numbers 
    {
        int len=d+1;//with flag=1 Situation
        while(s[d]=='0') d--;//Delete leading zero
        if(d<0)cout<<'0';//with flag=1 Situation
        for(int i=d; i>=0; i--) cout<<s[i];//First half of inverted output
        printf(".");//Characters in the middle
        while(s[l]=='0') l--;//Delete leading zero
        len++;//If you don't add 1, it becomes a judgment character. The following while Statement not executed directly
        while(s[len]=='0') len++;//Delete the zero after the decimal
        len--;//len--,For comparison
        if(l-1==len)cout<<'0';//If len and l-1 The value is equal, indicating that the decimal point on the right side is zero, directly output 0.
        for(int i=l-1; i>len; i--) cout<<s[i];//Output it
        return 0;//End procedure
    }//Think of yourself as the most difficult case, because the integer part and decimal part have to deal with and judge the case of zero, and the decimal part can not be zero in the end.
    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;
    }//If you think it's the simplest case, don't mention it.
}

Posted by drak on Sat, 11 May 2019 03:05:57 -0700