先说明一下本题的思路,本题要求的是进制匹配问题,第一行给四个数
第一个数 第二个数 tag 和进制数,
需要注意的是,此处的已知的进制数的,进制不会超出long long的范围
数也采用字符数组方式接收,为了把字符转换成数组,我们需要设置一个数组,把字符转换成数的形式,这也是本题中函数的init()的来源。
接收之后,我们需要把已知进制数转换成10进制数,同时找到未知进制数中最大的数位,我们需要明确的是,此数未知进制数的进制的最小值应该是这个最大数位加1,那么,如果可以得到有效的结果,我们需要明确一点,该未知进制数的最大进制应该不超过十进制数的已知进制数加1。那么我们得到了二分法条件下的left和right。接下来就是二分内容了,求解该未知数的十进制表示,如果得到负值(说明溢出,肯定比已知数大)或者大于该值,说明,此时进制太大,right=mid-1;缩小范围,如果此时正好相等,那么mid值就是我们要求的值。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long LL;
LL inf =(1LL<<63)-1;
LL map[256];
int n,maxnum=0;
void init()
{
for (char c='0';c<='9';c++)
map[c]=c-'0';
for (char c='a';c<='z';c++)
map[c]=c-'a'+10;
}
LL convert(char a[],int radix,LL t)
{
int len=strlen(a);
LL total=0;
for (int i=0;i<len;i++)
{
total=total*radix+map[a[i]];
if (total>t)
return -1;
}
return total;
}
LL binarysearch(LL left,LL right,char n2[],LL t)
{
LL mid;
while(left<=right)
{
mid=(left+right)/2;
LL ans=convert(n2,mid,t);
if(ans<0||ans>t)
right=mid-1;
else if (ans==t)
return mid;
else
left=mid+1;
}
return -1;
}
int findlargestradix(char a[])
{
int len=strlen(a),max=-1;
for (int i=0;i<len;i++)
{
if (map[a[i]]>max)
max=map[a[i]];
}
return max;
}
int main()
{
char n1[15],n2[15],temp[15];
int tag;
LL radix;
init();
scanf("%s %s %d %lld",n1,n2,&tag,&radix);
if(tag==2)
{
strcpy(temp,n1);
strcpy(n1,n2);
strcpy(n2,temp);
}
LL t=convert(n1,radix,inf);
LL low=findlargestradix(n2)+1;
LL high=t+1;
LL ans=binarysearch(low,high,n2,t);
if(ans==-1)
printf("Impossible");
else
printf("%lld",ans);
}