PAT甲级1010 Radix

思路很简单,把两个数分别转为 10 进制,然后进行比较。

主要有几个坑:

  1. radix 可能会很大(在题目中没有说明),要用 long long(经测试,能装下 tag 指定的数)
  2. 要用二分搜索答案,否则会超时
  3. 二分的初始上下界为 tag 指定的数值+1+1(一个+1是因为左闭右开,另一个是因为可能会有 a 10 2 10 这样的样例) 和 另一个数的最大位数+1(显然)
  4. 若二分时 mid 过大,可能会导致结果为负数,要将这个可能加入判断中
#include 
#define ll long long
using namespace std;
string n1, n2;
int tag;
ll radix;

void read() {
    cin >> n1 >> n2 >> tag >> radix;
}

int c2dec(char c) {
    if (c >= '0' && c <= '9') {
        return c - '0';
    } else if (c >= 'a' && c <= 'z') {
        return c - 'a' + 10;
    } else {
        return c - 'A' + 10;
    }
}

ll x2dec(string x, ll r) {
    ll decx = 0;
    for (int i = 0; i < x.length(); ++i) {
        decx *= r;
        decx += c2dec(x[i]);
    }
    return decx;
}

int findMin(string x) {
    int maxc = 0;
    for (int i = 0; i < x.length(); ++i) {
        maxc = max(maxc, c2dec(x[i]));
    }
    return maxc+1;
}

void solve() {
    if (tag == 2) swap(n1, n2);

    ll decn1 = x2dec(n1, radix);
    ll left = findMin(n2), right = decn1+2;
    while (left < right) {
        ll mid = left + (right-left)/2;
        ll decn2 = x2dec(n2, mid);
        if (decn1 == decn2) {
            cout << mid << endl;
            return;
        } else if (decn1 < decn2 || decn2 < 0) { //decn2为负,说明radix太大    
            right = mid;
        } else {
            left = mid + 1;
        }
    }

    cout << "Impossible" << endl;
}

int main() {
    read();
    solve();
    return 0;
}

 

你可能感兴趣的:(PAT甲级题解)