1010 Radix

Posted ruruozhenhao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1010 Radix相关的知识,希望对你有一定的参考价值。

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
 

Sample Output 1:

2
 

Sample Input 2:

1 ab 1 2
 

Sample Output 2:

Impossible

 

题意:使两个不同进制的数相等。

 

Code:

#include<iostream>
#include<algorithm>

using namespace std;

int arr[26] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
                21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 
                31, 32, 33, 34, 35};

int Tochange(char c) {
    int t;
    if (c > ‘9‘) {
        t = arr[c-‘a‘];
    } else {
        t = c - ‘0‘;
    }
    return t;
}

int StrToNum(string s, int n) {
    int ret = 0;
    int b, e = 1;
    reverse(s.begin(), s.end());
    for (int i = 0; i < s.length(); ++i) {
        b = Tochange(s[i]);
        if (b >= n) return -1;
        ret += b * e;
        e *= n;
    }
    return ret;
}

int main() {
    string N1, N2;
    int tag, t;
    int redix;

    cin >> N1 >> N2 >> tag >> redix;

    t = redix;

    int num1, num2;
    if (tag == 1) {
        num1 = StrToNum(N1, t);
        for (int i = 2; i <= 35; ++i) {
            num2 = StrToNum(N2, i);
            if (num1 == num2) {
                cout << i;
                return 0;
            }
        }
    } else {
        num2 = StrToNum(N2, t);
        for (int i = 2; i <= 35; ++i) {
            num1 = StrToNum(N1, i);
            if (num1 == num2) {
                cout << i;
                return 0;
            }
        }
    }

    cout << "Impossible";

    return 0;
}

  

这个代码通过了部分测试数据,有些数据返回的结果是Wrong Answer。

 


 

看了一下别人的代码,发现上面出错的原因在于,在寻找基数的时候寻找的范围并不是在2~36之间,而是在2~+∞。如果还是用原来的遍历查找的话肯定是不行的,所以想到用二分法来查找。在用二分法来查找的时候要注意

    while (low <= high) {

    }

while循环中是<=而不是<。

还有就是35的10次方是一个很大的数字,开数据类型的时候要开成long long类型的。其实开成long long类型的之后还是会溢出,成为负数,所以在检测的时候会有这一句代码

else if (temp < 0 || temp > n) high = mid - 1;

  

Code:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cctype>

using namespace std;

int arr[26] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
                21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 
                31, 32, 33, 34, 35};

int Tochange(char c) {
    int t;
    if (c > ‘9‘) {
        t = arr[c-‘a‘];
    } else {
        t = c - ‘0‘;
    }
    return t;
}

long long StrToNum(string s, long long n) {
    int b;
    long long ret = 0;
    long long e = 1;
    reverse(s.begin(), s.end());
    for (int i = 0; i < s.length(); ++i) {
        b = Tochange(s[i]);
        ret += b * e;
        e *= n;
    }
    return ret;
}

void findRedix(string s, long long n) {
    long long temp;
    char c = *max_element(s.begin(), s.end());
    long long low = Tochange(c) + 1;
    long long high = max(low, n);
    while (low <= high) {
        long long mid = (low + high) / 2;
        temp = StrToNum(s, mid);
        if (temp == n) {
            cout << mid;
            return ;
        }
        else if (temp < 0 || temp > n) high = mid - 1;
        else low = mid + 1;
    }
    cout << "Impossible";
}

int main() {
    string N1, N2;
    int tag, redix;

    cin >> N1 >> N2 >> tag >> redix;

    long long num1, num2;
    if (tag == 1) {
        num1 = StrToNum(N1, redix);
        findRedix(N2, num1);
    } else {
        num2 = StrToNum(N2, redix);
        findRedix(N1, num2);
    }

    return 0;
}

  

 

以上是关于1010 Radix的主要内容,如果未能解决你的问题,请参考以下文章

PAT-1010 Radix

PAT 1010. Radix

PAT甲级 1010 Radix

PAT甲组 1010 Radix (二分)

1010 Radix (25 分) 暴力枚举

PAT甲级 1010 Radix