这题太狗了,我还以为它是纯纯的暴力,结果24分…
只好默默地学了二分,还是24分… 这一分是因为题目没给数据范围,我以为进制最大为36,作死地设了个MA,
这题不会爆long long 对于第一个数
对于第二个数的二分时候我们可能会爆long long 那咋整? 特判!如果我们在把第二个数转为十进制的时候炸了(刚好它会变为一个负数,而不可能变为自然数)
此时我们把它转为一个比第一个数大3的数就好啦
主要是想到了二分,不知道如何解决爆long long
好好反思
上代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int r(char c)
{
if(isalpha(c)) return c-'a'+10;
return c - '0';
}
int main()
{
ll sum = 0,ok = 0;
int jin,tag,w1[20],w2[20];
string s1,s2,t;
cin>>s1>>s2>>tag>>jin;
if(tag == 2)
{
t = s2; s2 = s1; s1 =t;
}//让s1 为已知进制
int n1 = s1.size(),n2 = s2.size();
//字母化数字好看
for (int i = 0; i < n1; i++) w1[i] = r(s1[i]);
for (int i = 0; i < n2; i++) w2[i] = r(s2[i]);
//判断是否超进制如果超则不行
for (int i = 0; i < n1; i++) {
if(w1[i] >= jin){
sum = -1;break;
}
else{
sum = sum*jin+w1[i];
}
}
if(sum == -1) printf("Impossible\n");
else{
//确立一下 l 的 范围,至少要大于数字内的最大数
ll l = 0,r = sum+5; //r 等于sum+5 是因为下面二分不会取到r这个点
for (int i = 0; i < n2; i++)
{
if(l < w2[i]) l = w2[i];
}
l++;
//纯纯的二分
while(l < r){
ll mid = (r+l)/2;
ll sum2 = 0;
for (int i = 0; i < n2; i++)
{
sum2 = sum2*mid + w2[i];
if(sum2 < 0)
{
sum2 = sum+3; break;//溢出了
} //溢出的数肯定比sum大
}
if(sum2 >= sum)
{
r = mid; if(sum2 == sum) ok = 1;
}
else l = mid+1;
}
if(ok) printf("%lld\n",l);
else printf("Impossible\n");
}
return 0;
}