最开始以为是简单的暴力水题。额,实际上,是一道深刻的阅读理解题~~
题中 if the solution is not unique, output the smallest possible radix. 明显是将人忽悠到暴力方向去的。再加上题中给出的数据中每位数都是小于35(‘z’) 。嗯暴力一发,发现眼前一片绿_(:з」∠)_
后来想想,这题也没给出radix具体范围,并且可以证明答案一定是唯一的(假设已经有一个满足条件的进制,换个进制,值能和之前一样??? 不用多想答案具有唯一性!) 再一次佩服一波出题人的误导技能,题意用if条件句,emmm 没毛病,
非暴力的做法,radix显然与其值成非线性单调递增。那就是二分答案咯,二分区间?2 到 long long上限? 忽略十位的串求和 * logn 还是太大,会超时。但这只是个radix 基数,基数都过大,值肯定爆到银河系。判断保证基数不会大到令其值超long long,作二分的右剪枝。
关于二分区间,我看了网上思路,有很多版本都错了,没必要将上限和下限比较取较大作上限。已知串的值若小于带求串的最大数字,一定是Impossible!
最后我用的范围其实是 (待求串的最大数字+1 ,已知串的数值 + 1)
我学到了:很不习惯没设置数据范围的题,只能靠猜!感觉被题意坑了。还是不能小看了PAT, 以后认真点,可多长个心眼吧!~!
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
string s[3];
LL N[3],ans = -1;
inline int toNum(char c)
{
if(c>='0' && c<='9') return c - '0';
return c - 'a' + 10;
}
inline LL calRadix(string s, LL radix)
{
LL ret = 0;
LL t = 1;
for(int i = s.length() - 1; ~i; i--)
{
ret += t * toNum(s[i]);
t *= radix;
}
return ret;
}
inline bool judge(int tag, LL radix)
{
N[tag] = calRadix(s[tag],radix);
LL l = toNum(*max_element(s[tag^3].begin(),s[tag^3].end())) + 1;
LL r = N[tag] + 1;
while(l <= r) //二分答案
{
LL mid = (l + r) >> 1;
//cout << l <<" " << mid << " " << r<< endl;
N[tag^3] = calRadix(s[tag^3],mid);
if(N[tag^3] < 0 || N[tag] < N[tag^3] ) r = mid - 1;
else l = mid + 1;
if(N[tag] == N[tag^3]) {
ans = mid;
return true;
}
}
return false;
}
int main(void)
{
//freopen("in.txt","r",stdin);
cin >> s[1] >> s[2];
LL tag, radix;
cin >> tag >> radix;
judge(tag,radix)? cout << ans: cout <<"Impossible";
}