PAT-甲级-1010 Radix(25)

原文链接:PAT-甲级-1010

题目大意:

给定两个数和其中一个数a的基数radix(进制),另外一个数b可以是任意进制的情况下,看看两个数能不能相等。

解题思路:

刚开始的思路就是先求出给定进制的数,然后寻找另个一个数中每一位的最大值rdx,然后从rdx开始遍历,并计算其相应的十进制数res,直到大于等于a相应的十进制数。等于就是找到了,大于就是没有。写完信心满满,然后超时了:)
然后换成二分查找法就可以不会超时了,注意不要用递归。

注意事项:

1、需要用long long
2、计算过程中long long 也会溢出,所以要判断res是不是小于零
3、需要注意 11 b 1 10 的情况
4、要用二分

代码:

#include<iostream>
#include<cmath>
#include<string>
#include<cstring>

using namespace std;

typedef long long LL;

//将字符rdx换成其所对应的十进制数
int get_dex(char rdx)
{
    return rdx > '9' ? rdx - 'a' + 10 : rdx - '0';
}

//获取rdx进制下的a的十进制的值
LL get_a(string a, LL rdx)
{
    LL num = 0;
    for (int i = 0; i < a.length(); i++) {
        num = num * rdx + get_dex(a[i]);
    }
    return num;
}

//利用二分法寻找结果
LL btsearch(const string a, LL left, LL right, LL res)
{
    while (left <= right) {
        LL mid = (left + right) / 2;
        LL a_dex = get_a(a, mid);
        if (a_dex == res) return mid;
        else if (a_dex > res || a_dex < 0) right = mid - 1;//防止radix溢出
        else left = mid + 1;
    }
    return -1;
}

int main()
{
    LL a, rdx, high;
    int tag;
    string n1, n2, b;
    cin >> n1 >> n2 >> tag >> rdx;
    if (tag == 1) {         //根据tag获取基数
        a = get_a(n1, rdx);
        b = n2;
    }
    else {
        a = get_a(n2, rdx);
        b = n1;
    }
    rdx = 0 ;
    //寻找b(要转换的值)中每位对应的最大的值
    for (int i = 0; i < b.length(); i++)
        rdx = get_dex(b[i]) > rdx ? get_dex(b[i]) : rdx;
    rdx++;
    high = a > rdx ? a : rdx + 1;// eg:11 b 1 10 处理仅一位且相等的情况
    rdx = btsearch(b, rdx, high, a);//用二分法寻找相应的基数
    if (rdx != -1) cout << rdx << endl;
    else cout << "Impossible\n";
    return 0;
}
点赞