題名:
2つの数を与え、1つの基数を与え、他の数が特定の基数の下で前の数と等しいかどうかを尋ねます。
回答:
10進数に変換する必要があります。次に、最初の数値と比較するために、ベースごとに別の数値を10進数に変換します。
- タイトルには0〜10とa〜zしかありませんが、ベースが36しかないという意味ではありません。ベースが非常に大きい場合があり、2つに分割する必要があります。
- 二分法の最初の左の境界は簡単に見つけることができ、右の境界は最大に設定できます(左の境界、10進数の別の数値)
- 二分法の過程で、底が大きすぎると、longlongが発生する可能性があります。負の数が得られた場合は、この時点で底が大きすぎることを意味します。
実際、この質問は非常に問題があると思います。質問には触れませんでしたが、ほとんどの場合、16進表記の数値は10進数に変換しても暴力的ではありません。私も推測しました。これを行った後、ACM標準に従ってPATを要求することはできません。
ACコード:
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define lep(i,a,b) for(int i=(a);i>=(b);i--)
#define lepp(i,a,b) for(int i=(a);i>(b);i--)
#define pii pair<int,int>
#define pll pair<long long,long long>
#define mp make_pair
#define All(x) x.begin(),x.end()
#define ms(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define INFF 0x3f3f3f3f3f3f3f3f
#define multi int T;scanf("%d",&T);while(T--)
using namespace std;
typedef long long ll;
typedef double db;
const int N=2e5+5;
const int mod=1e9+7;
const db eps=1e-6;
const db pi=acos(-1.0);
string n1,n2;
int tag,radix;
ll num1,num2;
int change(char c){
if(c>='0'&&c<='9') return c-'0';
return c-'a'+10;
}
ll cal(string s,int r){
int l=s.size();
ll res=0;
repp(i,0,l){
res=res*r+change(s[i]);
}
return res;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("D:\\work\\data.in","r",stdin);
#endif
cin>>n1>>n2>>tag>>radix;
if(tag==2) swap(n1,n2);
num1=cal(n1,radix);
int l2=n2.size(),minn=0;
repp(i,0,l2){
minn=max(minn,change(n2[i]));
}
ll l=minn+1,r=max(l,num1);
while(l<r){
ll mid=(l+r)>>1;
num2=cal(n2,mid);
if(num2<0||num2>=num1) r=mid;
else l=mid+1;
}
if(cal(n2,l)==num1) cout<<l<<endl;
else cout<<"Impossible"<<endl;
}