PAT A1010 Radix (25 分)

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 N1​​ and N2​​, 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

Sample Output 1:

2

Sample Input 2:

1 ab 1 2

Sample Output 2:

Impossible
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
long long str2num(string s, long long radix){
    long long num = 0;
    for (int i = 0; i < s.length(); i++){
        if (s[i] >= '0' && s[i] <= '9')num = num + (s[i] - '0')*pow(radix, s.length() - i - 1);
        else if (s[i] >= 'a' && s[i] <= 'z')num = num + (s[i] - 'a' + 10)*pow(radix, s.length() - i - 1);
    }
    return num;
}
long long min_radix(string s){
    long long max_r = 0;
    for (int i = 0; i < s.length(); i++){
        long long tmp;
        if (s[i] >= '0' && s[i] <= '9')tmp = s[i] - '0';
        else if (s[i] >= 'a' && s[i] <= 'z')tmp = s[i] - 'a' + 10;
        if (tmp>max_r)max_r = tmp;
    }
    return max_r+1;
}
int main(){
    string n1, n2;
    long long num1 = 0, num2 = 0;
    long long tag, radix;
    long long min_r = 0, res = 0, le, ri, mid;
    cin >> n1 >> n2 >> tag >> radix;
    if (tag == 1){
        num1 = str2num(n1, radix);
        min_r = min_radix(n2);

    }
    else{
        num1 = str2num(n2, radix);
        min_r = min_radix(n1);
    }
    le = min_r;
    ri = max(le,num1);
    while (le <= ri){
        mid = (le + ri) / 2;
        num2 = str2num(tag==1?n2:n1, mid);
        if (num2<0 || num2 > num1)ri = mid - 1;
        else if (num2 < num1)le = mid + 1;
        else{
            res = mid;
            break;
        }
    }

    if (res != 0)printf("%d", res);
    else printf("Impossible");
    system("pause");
}

注意点:第一:两个输入题目保证不超过10位,但没说几进制,所以可能会很大,不过好在测试数据都没有超过long long。

第二:针对这种两个换一换的情况最好写函数,简洁明了,还可以直接用swap函数(algorithm头文件里)

第三:由于没有明确上界,需要自己判断

第四:范围太大,逐个遍历会超时,要用二分法

第五:由于指定数不超过long long,在特定radix下得到的值溢出long long(小于0),说明太大

第六:基数的下限通过遍历字符串得到,下限肯定比最大的数大1

第七:上界为ri = max(le,num1);,这里一直想不通,其实是这样的,如果已知数比最小基数要小,用最小基数也还是可能算出已知数来的,比如已知10进制的8,未知数为8,9进制就可以了。

猜你喜欢

转载自www.cnblogs.com/tccbj/p/10371795.html