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;
}

  

 

posted @ 2020-03-28 12:09  Veritas_des_Liberty  阅读(212)  评论(0编辑  收藏  举报