关键:注意这里radix没有范围,可以大到longlong溢出,所以比较两个数可以用剪枝方法判断,即设置一个特定的比较方法当溢出时直接返回,另外查找用二分法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
long long inf = (1LL<<63)-1;
long long Map[256];
long long change(char* a,long long r){
int len=strlen(a);
long long res=0;
long long d=1;
while(len--){
res+=Map[a[len]]*d;
d*=r;
}
return res;
}
long long findLowRadix(char* p){
long long len = strlen(p);
long long low = 0;
long long num;
for(long long i=len-1;i>=0;i--){
num=Map[p[i]];
if(num+1>low)low=num+1;
}
return low;
}
int compare(char* p,long long radix ,long long target)
{
long long len=strlen(p);
long long m = 1;
long long num = 1;
long long sum = 0;
for(long long i=len-1;i>=0;i--)
{
if(p[i]>='a'&&p[i]<='z')
num= p[i] - 'a' + 10;
else if(p[i]>='0'&& p[i]<='9')
num=p[i] - '0';
sum+=num*m;
m*=radix;
if(sum>target) //avoid overflow
return 1;
}
if(sum>target)
return 1;
else if(sum<target)
return -1;
else
return 0;
}
long long Binary_Search(char *p,long long low,long long high,long long top){
long long mid=low;
long long tmp;
while(low<=high){
tmp=compare(p,mid,top);
if(tmp>0){
high=mid-1;
}else if(tmp<0){
low=mid+1;
}else return mid;
mid=(low+high)/2;
}
return -1;
}
int main()
{
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif // LOCAL
for(char c='0';c<='9';c++)
Map[c]=c-'0';
for(char c='a';c<='z';c++)
Map[c]=c-'a'+10;
char a[14],b[14];
long long radix,tag,low,high,res,taget;
cin>>a>>b>>tag>>radix;
if(1==tag){
taget=change(a,radix);
low=findLowRadix(b);
high=(taget+1>low+1)?taget+1:low+1;
res=Binary_Search(b,low,high,taget);
if(res==-1)cout<<"Impossible";
else cout<<res<<endl;
}
if(2==tag){
taget=change(b,radix);
low=findLowRadix(a);
high=(taget+1>low+1)?taget+1:low+1;
res=Binary_Search(a,low,high,taget);
if(res==-1)cout<<"Impossible";
else cout<<res<<endl;
}
return 0;
}
简化
#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#define FOR(i, x, y) for(int i = x; i <= y; i++)
#define rFOR(i, x, y) for(int i = x; i >= y; i--)
#define MAXN 610
#define MT(x,i) memset(x,i,sizeof(x))
#define oo 0x3f3f3f3f
using namespace std;
typedef long long ll;
ll inf=(1ll<<63)-1;
ll change(char str[],ll radix)
{
int len=strlen(str);
ll ans=0;
FOR(i,0,len-1)
{
if(str[i]<='9'&&str[i]>='0'){
ans=ans*radix+str[i]-'0';
}else{
ans=ans*radix+str[i]-'a'+10;
}
if(ans<0||ans>inf)return -1;
}
return ans;
}
int main()
{
#ifdef LOCAL
freopen("data.in","r",stdin);
#endif // LOCAL
ll n1,n2,tag,radix;
char s1[12],s2[12];
scanf("%s%s%lld%lld",s1,s2,&tag,&radix);
if(tag==2){
char tmp[12];
strcpy(tmp,s1);
strcpy(s1,s2);
strcpy(s2,tmp);
}
n1=change(s1,radix);
int len=strlen(s2);
int ra=0;
FOR(i,0,len-1)
{
int tmp;
if(s2[i]<='9'&&s2[i]>='0') tmp=s2[i]-'0';
else tmp=s2[i]-'a'+10;
ra=max(ra,tmp);
}
ra++;
ll low=ra;
ll high=max(n1,low)+1;
ll mid;
while(low<=high)
{
mid=(low+high)/2;
n2=change(s2,mid);
if(n2<n1&&n2!=-1){
low=mid+1;
}else if(n2>n1||n2==-1){
high=mid-1;
}else{
printf("%lld",mid);return 0;
}
}
printf("Impossible");
return 0;
}