题意:
给你两个正整数n1,n2,然后是tag,radix
tag==1,表示n1是radix进制数,tag==2,表示n2是radix进制数
问你,如果要使n1=n2,另外一个数要是多少进制数?,不可能输出impossible
解析:
写这道题不是这道题有多难,而是这道题有多坑.....
这道题radix答案取值范围可以达到long long的水平,但是它又能保证你求答案的那个数(这里假定为n2了),
的十进制表示的形式的范围在long long 里面......但是这些题目都没有告诉你,要你自己猜..........
所以最暴力的方法就是从2->long long 都枚举答案,但这样会T,所以用二分枚举就可以了
并且这里你用二分的mid,当作进制去将n2转换成十进制时,如果转换出来的数爆long long 了(即值<0),.说明r太大了,要缩小.....
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
const int N = 1e4+100;
const ll INF = 0x3f3f3f3f3f3f3f3f;
char s[2][11];
int main()
{
int tag,radix;
int n=0;
scanf("%s%s%d%d",&s[0],&s[1],&tag,&radix);
if(tag==2) n^=1;
if(strcmp(s[0],s[1])==0)
{
printf("%d\n",radix);
return 0;
}
ll x=0;
for(int i=0;s[n][i];i++)
{
x=x*radix;
if(s[n][i]>='0'&&s[n][i]<='9') x+=s[n][i]-'0';
else x+=s[n][i]-'a'+10;
}
int m=n^1;
int flag=0;
int beg=1;
for(int i=0;s[m][i];i++)
{
int c=0;
if(s[m][i]>='0'&&s[m][i]<='9') c+=s[m][i]-'0';
else c+=s[m][i]-'a'+10;
beg=max(beg,c+1);
}
ll l=beg;
ll r=INF;
ll y;
while(l<r)
{
ll mid=(l+r)>>1;
y=0;
for(int j=0;s[m][j];j++)
{
y=y*mid;
if(y<0) break;
if(s[m][j]>='0'&&s[m][j]<='9') y+=s[m][j]-'0';
else y+=s[m][j]-'a'+10;
if(y<0) break;
}
if(y<0||y>x) r=mid;
else if(y==x) flag=mid,r=mid;
else l=mid+1;
}
y=0;
for(int j=0;s[m][j];j++)
{
y=y*l;
if(y<0) break;
if(s[m][j]>='0'&&s[m][j]<='9') y+=s[m][j]-'0';
else y+=s[m][j]-'a'+10;
if(y<0) break;
}
if(y==x) flag=l;
if(flag) printf("%d\n",flag);
else printf("Impossible\n");
}