PAT class a 1010 Radix personal understanding

Posted by phpScott on Sun, 21 Nov 2021 19:43:49 +0100

1010
Liu Shen
It has been updated locally recently
&Goodbye, firefly&

1010 Radix (25 branch)
Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The answer is yes, if 6 is a decimal number and 110 is a binary number.

Now for any pair of positive integers N 
1
​
  and N 
2
​
 , your task is to find the radix of one number while that of the other is given.

Input Specification:
Each input file contains one test case. Each case occupies a line which contains 4 positive integers:


N1 N2 tag radix
Here N1 and N2 each has no more than 10 digits. A digit is less than its radix and is chosen from the set { 0-9, a-z } where 0-9 represent the decimal numbers 0-9, and a-z represent the decimal numbers 10-35. The last number radix is the radix of N1 if tag is 1, or of N2 if tag is 2.

Output Specification:
For each test case, print in one line the radix of the other number so that the equation N1 = N2 is true. If the equation is impossible, print Impossible. If the solution is not unique, output the smallest possible radix.

Sample Input 1:
6 110 1 10
 No blank lines at the end
Sample Output 1:
2
 No blank lines at the end
Sample Input 2:
1 ab 1 2
 No blank lines at the end
Sample Output 2:
Impossible
 No blank lines at the end

There is no clue when doing this problem by yourself. The code is supplemented after learning later. If the following personal explanation is not understood, you can refer to the articles of the above bloggers

The meaning of this question is: give two numbers A and B, and then give the base number of one of them. When the values of A and B are equal in the same base, what is the base number of A?

Dasilu:
Convert the two numbers A and B into decimal numbers, and then compare the two numbers. If they are equal, output the hexadecimal number of A at this time (assuming that the title has given the hexadecimal number of B), otherwise output impossible
==**
Practice:
1. Determine the input data type. A and B may contain numbers and letters, so a and B are stored in strings. The hexadecimal numbers of flag and a are not given size and have no letters. However, since the title mentions that a and B have more than 10 digits, it is safe to use a larger long for storage (int stores 10 ^ 9)

2. First, convert A into decimal number (in fact, you can select any number of decimal numbers here, just to compare the last two numbers in the same decimal). The conversion method traverses the string from back to front. Since characters may appear in the string, this part needs to be specially processed

3. Brutally exhaustive hexadecimal number, equivalent to A when trying to convert B to decimal. The difficulty here is the exhaustive range. The first is the lower bound. Because the title gives the representation of B in A certain binary state, the maximum number + 1 that can appear in B is the minimum binary number (similar to the decimal system, each digit can only appear 9 at most), that is, to make the representation of B as given in the title, its binary number must be as above; The second is the upper bound. The clever thing here is that, taking the decimal 6 and 110 in the example as an example, if the decimal of 110 is equal to 6 at this time, what should the decimal number of 110 be? Suppose it's not 110 but 010 (why? We'll talk about it later). Considering that the number of each digit is multiplied by the power of the decimal number, and the number of the second digit is multiplied by the current decimal number, that is, 1 in binary 10 is multiplied by the power of 2 in binary, then if we want 010 to be equal to 6 in decimal, Then the hexadecimal number of 010 can only be hex. When 010 becomes larger (e.g. 011, 100), the hexadecimal number must be reduced in order to maintain equality. Therefore, when our number is not 010 but 110, the hexadecimal number of 110 must be smaller than the hexadecimal number of 010 (HEX). Therefore, hex can be regarded as the maximum value of the hexadecimal number of 110 (this explains why the above example is 010).
This conclusion is universal. For each number, the upper bound of its hexadecimal number is the other number itself.

Conclusion: the lower bound of binary conversion is the maximum number + 1 that can appear in B, and the upper bound is the other given number itself.

In the implementation, there may be an upper bound < = lower bound. At this time, the upper bound should be set to a larger value

4. The violent exhaustive search is optimized into binary search. Since the hexadecimal numbers (that is, the upper and lower bounds we set) are orderly, the binary search can be used to optimize the time complexity of the original exhaustive O(n) to O(logn).
Binary search time complexity

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

long long toDecimal(string s,long long base){
    long long res = 0;
    int index = 0,temp = 0;
    for(int i = s.size() - 1;i >= 0;--i){
        temp = isdigit(s[i])?s[i] - '0':s[i] - 'a' + 10;
        res += temp * pow(base,index++);
    }
    return res;
}

long long find_radix(string str,long long d){
    char temp = *max_element(str.begin(),str.end());
    long long low = (isdigit(temp)?temp - '0':temp - 'a' + 10) + 1;
    long long high = max(d,low);
    while(low <= high){
        long long mid = (low + high) / 2;
        long long t = toDecimal(str,mid);
        if(t < 0||t > d){
            high = mid - 1;
        }
        else if(t < d){
            low = mid + 1;
        }
        else{
            return mid;
        }
    }
    return -1;
}

int main(){
    string a,b;
    long long flag,base;
    cin >> a >> b >> flag >> base;
    if(flag == 2){
        swap(a,b);
    }
    long long result_radix = find_radix(b,toDecimal(a,base));
    if(result_radix == -1){
        cout << "Impossible" << endl;
    }
    else{
        cout << result_radix << endl;
    }
    return 0;
}

Topics: C C++ Algorithm