1010 Radix (25 分)
题目大意:
样例中给出了4个数据 分别是
数字n1 n2
一个标记
数字dec 某个数的进制
题目要求
如果标记是1 那么dec就是数字n1的进制
如果标记是2 那么dec就是数字n2的进制
我们要做的是算出另一个数字在多少进制的情况下会和原本数字相等
分析:
这道题需要把先知道的那个数字转化为十进制,再把后来的那个dec进制的数字也转化为十进制,如果相等则输出这个dec就完事了,如果没有这种情况就输出不可能
这个题是一个有很多很多很多很多很多坑的题
1 不要被题目带偏离 这个题没说最大就是36进制,它有可能无限大
2 因为进制有可能无限大所以, 再寻找哪个进制合适的时候, 暴搜肯定会超时, 所以我们用二分
3 因为进制有可能无限大, 所以后来的那个数的dec进制转化为十进制的过程中有可能会溢出也就是超过long long的数据范围
AC代码:
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#define LL long long
using namespace std;
string s1,s2;
int flag;
bool Isdigit(char ch){
if(ch>='0' && ch<='9')
return true;
return false;
}
LL GetNum(string s,LL dec){//用于将s对应的数字的dec进制 转化为 十进制
LL sum=0,Per_digit=0;
int len=s.length();
for(int i=0;i<len;i++){
Per_digit=(Isdigit(s[len-1-i])==true ? (s[len-1-i]-'0') : (s[len-1-i]-'a'+10));
if( Per_digit * (LL)pow(dec,i)<0 )
return -1;
sum+=Per_digit * (LL)pow(dec,i);
}
return sum;
}
LL GetAns(string s,LL Sum){//判断s的几进制和Sum相等
LL dec,Max=2,ans=-1;//进制
for(int i=0;i<s.length();i++){
dec=(Isdigit(s[i])==true ? (s[i]-'0'+1) : (s[i]-'a'+10+1) );
Max=max(Max,dec);
}
LL low=Max;//应取进制的下限
LL high=max(low,Sum);//应取进制的上限
while(low<=high){
LL mid=(low+high)/2;
LL Num=GetNum(s,mid);
//两种情况 一种大于了另一个数字 一种超出了LL的范围 都说明进制取大了
if(Num>Sum || Num<0)
high=mid-1;
else if(Num==Sum){
ans=mid;
high=mid-1;
}
else
low=mid+1;
}
return ans;
}
int main(){
LL dec;
cin>>s1>>s2>>flag>>dec;
LL ans= (flag==1 ? GetAns( s2,GetNum(s1,dec) ) : GetAns( s1,GetNum(s2,dec) ) );
if(ans != -1)
cout<<ans<<endl;
else
cout<<"Impossible"<<endl;
return 0;
}