1010 Radix
题目大意
题目给出两个数,给出其中一个数的进制,要求另一个数的进制是多少时,能够使二者相等,如果找不到就返回Impossible
算法思想
- 这道题的坑还是挺多的,第一个就是必须要用long long,不然有些数太大
- 找的时候要用二分法,不然测试点7过不去,一直超时,在我持续24分很久之后才意识到
- 二分法的上下界也有要求,下界是要求的那个数中,所包含的数字最大值加1,比如213,最大数是3,那么下界就是3+1=4,
- 上界是给出那个数转为十进制后加1
- 还有就是溢出时,得到的值会是负的,这就需要二分法时进行判断,负的仍然是过大的
代码
#include<iostream>
#include<vector>
using namespace std;
long long ex(long long rad, int k)//转十进制时要乘的值
{
long long sum=1;
for (int i = 0; i < k-1; i++)
{
sum = sum * rad;
}
if (sum < 0)//溢出
sum = -1;
return sum;
}
long long tra(long long rad, string s)//转十进制数
{
long long ten = 0;
for (int i = 0; i < s.size(); i++)
{
if (s[i] >= '0' && s[i] <= '9')//需要判断0-9还是a-z
{
ten += (s[i] - '0') * ex(rad, s.size() - i);
}
else
{
ten += (s[i] - 'a' + 10) * ex(rad, s.size() - i);
}
}
if (ten < 0)//溢出
ten = -1;
return ten;
}
int main()
{
vector<string>s(3);
long long tag1,tag2,rad1;
int i;
long long va[3];
cin >> s[1] >> s[2] >> tag1 >> rad1;//tag1是给出的,tag2是求的值
if (tag1 == 1)
tag2 = 2;
else
tag2 = 1;
va[tag1] = tra(rad1, s[tag1]);//转十进制
long long low = 2;
long long high = va[tag1]+1;//上界
long long mid;
for (i = 0; i < s[tag2].size(); i++)//求下界,下界是其包括的最大的数+1,不能直接赋2
{
if (s[tag2][i] >= '0' && s[tag2][i] <= '9')
{
if (s[tag2][i] - '0' + 1 > low)
{
low = s[tag2][i] - '0' + 1;
}
}
else
{
if (s[tag2][i] - 'a' + 11 > low)
{
low = s[tag2][i] - 'a' + 11;
}
}
}
while (low <= high)//二分法找基数,不然会超时
{
mid = (low + high) / 2;
va[tag2] = tra(mid, s[tag2]);
if (va[tag2] > va[tag1] || va[tag2]<0)//小于零时也算太大
{
high = mid - 1;
}
else if (va[tag2] < va[tag1])
{
low = mid + 1;
}
else if(va[tag2]==va[tag1])//目标找到
{
cout << mid;
return 0;
}
}
cout << "Impossible";
return 0;
}