這道題真的挺難全對的,考察的邊界非常多,而且還有陷阱。。。
1.當N1 == N2的時候,如果N1和N2均爲1,進制 = 2,否則輸出題目給定的radix,我一開始就忽略了這一點,這幾天刷pat總是會掉進各種各樣邊界的坑裏…gg
2.對於目標數據進制,這個進制不能小於2,而且最大進制其實並不侷限於36。。。因爲看到題目裏舉例的’a’-‘z’,想當然以爲在2-36進制裏找答案就行,結果——聽取wa聲一片
3.由第二點來看,這題就不能簡單枚舉了,因爲上界可能非常大,測試用例裏有個樣例專門讓你超時,最終就選則二分。接下來還需要考慮二分法搜索上下邊界。目標待求字符串的最小進制一定要比它所包含字符最大值還要大1,且最小值不能小於2進制,因爲單純輸入0和1的時候都算是2進制,例如N2=”456ad”,最大字符是’d’,所以最小應該是13+1=14。那麼它的上限是多少呢,上限當然不能超過另外一個數據的十進制大小,因爲N2不爲0情況下,最小個位數都是1,如果它的進制再超過N1的十進制數了的話,它在十進制下的數也就比N1還要大,不符合要求。
4.在二分過程中需要把另一個數也不斷轉換成十進制跟target數字進行比較,能沿用轉換任何進制到十進制的那個函數嗎?不能,因爲轉換過程中就有可能會爆long long,因此需要重新寫一個函數,在轉換的過程中就進行判斷,一旦非法越界立即return
#include <stdio.h>
#include <iostream>
using namespace std;
long long change(string num, long long rad)
{
long long ans = 0;
for(int i = 0 ; i < num.length(); i++)
{
if(num[i]>='0' && num[i] <= '9')
ans = ans*rad + num[i]-'0';
else
ans = ans*rad + num[i]-'a'+10;
}
return ans;
}
int comp(string num, long long rad, long long tag)
{
long long ans = 0;
for(int i = 0 ; i < num.length(); i++)
{
if(num[i]>='0' && num[i] <= '9')
ans = ans*rad + num[i]-'0';
else
ans = ans*rad + num[i]-'a'+10;
if(ans > tag) return 1;
}
if(ans < tag) return -1;
return 0;
}
int findl(string num)
{
int ans = -1, temp;
for(int i = 0 ; i < num.length(); i++)
{
if(num[i]>='0' && num[i] <= '9')
temp = num[i]-'0';
else
temp = num[i]-'a'+10;
if(temp > ans) ans = temp;
}
return ans + 1;
}
long long MAX(long long a, long long b)
{
return a>b?a:b;
}
long long binary(string num, long long tag)
{
long long l = findl(num), r = MAX(l,tag);
long long mid, flag;
while(l <= r)
{
mid = (l+r)/2;
flag = comp(num,mid,tag);
if(flag == 1)
r = mid -1;
else if(flag == -1)
l = mid +1;
else
return mid;
}
return -1;
}
int main()
{
string n1,n2;
long long tag,rad;
long long nn1, nn2;
cin >> n1 >> n2 >> tag>> rad;
long long ans ;
if(n1 == n2)
{
if(n1 == "1")
cout << "2" << endl;
else
cout << rad << endl;
}
else
{
if(tag ==1)
{
nn1 = change(n1,rad);
ans = binary(n2,nn1);
}
else
{
nn2 = change(n2,rad);
ans = binary(n1,nn2);
}
if(ans == -1)
printf("Impossible\n");
else
printf("%d\n",ans);
}
return 0;
}