题目
https://pintia.cn/problem-sets/994805342720868352/problems/994805507225665536
题意
直接解释样例
数"6"是10进制,猜数"110"的进制数,使得6==110
数"1"是2进制,猜数"ab"的进制数,使得1==ab
Sample Input 1:
6 110 1 10
Sample Output 1:
2
Sample Input 2:
1 ab 1 2
Sample Output 2:
Impossible
思路&坑点
题目没有规定进制的上限,理论上N2的最大进制是int_N1(即N1的十进制的值)
如边界情况:N1:zzzzzz N2:10
因此需要用二分法猜这个进制数,参考柳神题解(long long溢出变负数了,太强了吧)
顺序暴力只T了一个点,能得24分,写起来方便,好像也不错。。。
code(顺序暴力版)
/***************************
Hello World!
***************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ch_int(char x)
{
if(x>='0' && x<='9') return x-'0';
else return 10+(x-'a');
}
int main()
{
string N1,N2;
ll tag,radix;
cin>>N1>>N2>>tag>>radix;
if(tag==2) {
string temp=N1;
N1=N2;
N2=temp;
}
ll int_N1=0;
ll t=1;
for(ll i=N1.size()-1;i>=0;--i)
{
int_N1+=ch_int(N1[i])*t;
t*=radix;
}
//暴力猜 2-36进制。。。 //竟然没有规定进制的上线,啊啊啊啊啊啊啊啊啊
for(ll ra=2;ra<=max(int_N1,36ll);++ra)
{
//能不能用ra进制??判断
ll uuu=0;
for(ll i=0;i<N2.size();++i)
{
if(ch_int(N2[i])>=ra) uuu=1;
}
if(uuu) continue;
ll t=1;
ll int_N2=0;
for(ll i=N2.size()-1;i>=0;--i)
{
int_N2+=ch_int(N2[i])*t;
t*=ra;
}
if(int_N2==int_N1) {
//猜中
cout<<ra<<endl;
return 0;
}
else if(int_N2>int_N1) break;
}
cout<<"Impossible"<<endl;
return 0;
}
/***************************
The end!
***************************/
code(二分法)
/***************************
Hello World!
***************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ch_int(char x)
{
if(x>='0' && x<='9') return x-'0';
else return 10+(x-'a');
}
int main()
{
string N1,N2;
ll tag,radix;
cin>>N1>>N2>>tag>>radix;
if(tag==2) {
string temp=N1;
N1=N2;
N2=temp;
}
ll int_N1=0;
ll t=1;
for(ll i=N1.size()-1;i>=0;--i)
{
int_N1+=ch_int(N1[i])*t;
t*=radix;
}
//二分猜
ll ans=-1;
ll left=0,right;
//确定左边界
for(int i=0;i<N2.size();++i) {
if(ch_int(N2[i])>left) left=ch_int(N2[i]);
}
left++;
//确定右边界
right=max(left,int_N1);
while(left<=right)
{
ll ra=(left+right)/2;
//求int_N2
ll t=1;
ll int_N2=0;
for(ll i=N2.size()-1;i>=0;--i)
{
int_N2+=ch_int(N2[i])*t;
t*=ra;
}
//judge
if(int_N2==int_N1) {
//猜中,继续往左猜
ans=ra;
right=ra-1;
}
else if(int_N2>int_N1 || int_N2<0)//溢出变负数了,啊啊啊啊啊啊
{
right=ra-1;
}
else left=ra+1;
}
if(ans==-1) cout<<"Impossible"<<endl;
else cout<<ans<<endl;
return 0;
}
/***************************
The end!
***************************/