此题题意:
给你两个数,确定一个数的进制,然后判断另外一个数能否在合理的进制下表示。
如果采用简单的顺序查找,那么可呢会在测试点7运行超时。如果想要过掉这道题,那么要用上二分查找。
二分查找的难点在于选择哪一个区间作为查找的范围。首先来确定下界,下界一定是另外一个数的数位上最大的那一个数。
为什么呢?
因为在进制表示中,一个数每一位中最大的那个数一定是该进制所代表的数小的,例如2f这个数,f是里面最大的一个数,那
么它的进制中最小都应该是16。
下面来确定上界,
上界为被tag表示的那个数的10进制数。这样充分保证了及时数字很小也能表示成tag所表示的数。
下界max(s[i]),上界为max(s,L)
说点体会:
浙大出题出的 就是好,各种边边角角都考虑到了,我在我的change函数里面只是添加了一个等号,测试点18就过不去,
还有就是数字本身超出long long int的那种处理方式,之前没有考虑到相乘之后超过long long int怎么办,只是想着超过int的情况
,而实际上这道题是可能超过long long的,所以这时就需要对函数进行变化,因为tag所表示的值变成10进制后绝不会超过long long
所以只需要在每一次乘的时候与tag所表示的值进行比较,如果超出了,就代表着此时根本就不需要继续乘下去了,所以值保证不会爆掉
#include<iostream>
#include<string>
#include<fstream>
#include<cstring>
#include<climits>
#include<cstdio>
using namespace std;
#define LL long long
string N1, N2;
LL tag, radix;
LL tagN1, tagN2;
LL temptag;
LL change(int radix, string numm, int flag)
{
int length = numm.length();
LL sum = 0;
LL temp = 1;
for (int i = length - 1; i >= 0; i--)
{
if (numm[i] >= 'a'&&numm[i] <= 'z')
{
sum += (numm[i] - 'a' + 10)*temp;
}
else
{
sum += (numm[i] - '0')*temp;
}
temp *= radix;
//加了一个等号,测试点18就过不去,因为这里的等号不能代表能用此时的radix表示
if (sum > temptag && flag == 1)
return sum;
}
return sum;
}
LL getmaxnum(string s)
{
int length = s.length();
int num;
int max = 0;
for (int i = 0; i < length; i++)
{
if (s[i] >= 'a'&&s[i] <= 'z')
num = (s[i] - 'a' + 10);
else
num = s[i] - '0';
if (num>max)
max = num;
}
return max + 1;
}
void solve()//binary search
{
LL flag = -1;//flag has two condition -1 represent Impossible,others represent equal
LL number = 0;
LL L, R;
LL M;
string tempN;
if (tag == 1)
{
tempN = N2;
temptag = tagN1;
}
else
{
tempN = N1;
temptag = tagN2;
}
L = getmaxnum(tempN);
R = L > temptag ? L : temptag;
while (L <= R)
{
M = (L + R) >> 1;
number = change(M, tempN, 1);
if (temptag > number)
{
L = M + 1;
}
else if (temptag < number)
{
R = M - 1;
}
else if (temptag == number)
{
flag = M;
break;
}
}
if (flag == -1)
cout << "Impossible\n";
else
cout << flag << endl;
}
void input()
{
cin >> N1 >> N2 >> tag >> radix;
if (N1 == "1"&&N2 == "1")
{
cout << 2 << endl;
return;
}
if (N1 == N2)
{
cout << radix << endl;
return;
}
if (tag == 1)
{
tagN1 = change(radix, N1, 0);
}
else
{
tagN2 = change(radix, N2, 0);
}
solve();
}
int main()
{
input();
return 0;
}