原文链接: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;
}