PAT甲级1010 Radix (25分)
题目:
题目分析:运用二分法来处理
AC代码附上:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
ll map[256];//0~9,a~z,和0~35对应
ll inf=(1ll<<63)-1;//long long 的最大值2^63-1,注意加括号
void init(){
for(char c='0';c<='9';c++){
map[c]=c-'0';//将'0'-'9'映射到0-9
}
for(char c='a';c<='z';c++){
map[c]=c-'a'+10;//将'a'-'z'映射到10-35
}
}
ll convertNum10(char a[],ll radix,ll t){
//将a转换为十进制,t为上界
ll ans=0;
int len = strlen(a);
for(int i=0;i<len;i++){
ans=ans*radix+map[a[i]];//进制转换
if(ans<0||ans>t) return -1;
}
return ans;
}
int cmp(char N2[],ll radix,ll t){
//N2的十进制与t比较
int len = strlen(N2);
ll num = convertNum10(N2,radix,t);//将N2转换为十进制
if(num<0) return 1;//溢出,肯定是N2>t
if(t>num) return -1;//t较大,返回-1
else if(t==num) return 0;//相等,返回0
else return 1;//num较大,返回1
}
ll binarySearch(char N2[],ll left,ll right,ll t){
//二分求解N2的进制
ll mid;
while(left<=right){
mid=(right+left)/2;
int flag = cmp(N2,mid,t);
if(flag==0) return mid;//找到解,返回mid
else if(flag==-1) left=mid+1;//往右子区间查找
else right = mid-1;
}
return -1;//解不存在
}
int findLargestDigit(char N2[]){
int ans=-1,len=strlen(N2);
for(int i=0;i<len;i++){
if(map[N2[i]]>ans){
ans = map[N2[i]];
}
}
return ans+1;//最大的位数为ans,说明进制的底线是ans+1
}
char N1[20],N2[20],temp[20];
int tag,radix;
int main(){
init();
scanf("%s %s %d %d",N1,N2,&tag,&radix);
if(tag==2){
//交换N1和N2
strcpy(temp,N1);
strcpy(N1,N2);
strcpy(N2,temp);
}
ll t = convertNum10(N1,radix,inf);//将N1从radix进制转换为10进制
ll low = findLargestDigit(N2);
ll high = max(low,t)+1;//上界
ll ans = binarySearch(N2,low,high,t);//二分
if(ans==-1) printf("Impossible\n");
else printf("%lld\n",ans);
return 0;
}