注意点:进制的上界不是36,而是已知进制数的数值+1.
直接遍历会超时。找上下界
注意溢出
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
LL Map[256];
//将字符转换为数字
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;//将'a'~'z'映射到10~35
}
}
//将s从radix进制转化为十进制
LL tra(char s[],LL radix)
{
int len=strlen(s);
LL num=0;
for(int i=0;i<len;i++)
{
num=num*radix+Map[s[i]];
if(num<0)//num<0则发生溢出
return -1;
}
return num;
}
//二分查找进制(用递归会发生运行时错误)
LL select(char *s,LL num,LL low,LL high)
{
LL mid;
while(low<=high)
{
mid=(low+high)/2;
LL num1=tra(s,mid);
if(num1==num)
return mid;
if(num1<0||num1>num)
high=mid-1;
else
low=mid+1;
}
return -1;
}
//进制下界为最大位+1
int low(char s[])
{
int len=strlen(s);
int low=-1;
for(int i=0;i<len;i++)
{
if(low<Map[s[i]])
low=Map[s[i]];
}
return low+1;
}
int main()
{
init();
char s1[20],s2[20],temp[20];
int tag,radix;
LL num1,j,a,b;
scanf("%s %s %d %d",s1,s2,&tag,&radix);
if(tag==2)
{
strcpy(temp,s1);
strcpy(s1,s2);
strcpy(s2,temp);
}
num1=tra(s1,radix);
a=low(s2);//a为进制下界
if(a>num1)//b为进制上界(大于下界和num1)
b=a+1;
else
b=num1+1;
j=select(s2,num1,a,b);
if(j==-1)
cout<<"Impossible"<<endl;
else
printf("%lld\n",j);
return 0;
}