PAT 1010 Radix 进制转换+二分法
Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The answer is “yes”, if 6 is a decimal number and 110 is a binary number.
Now for any pair of positive integers N1 and N2, your task is to find the radix of one number while that of the other is given.
Input Specification:
Each input file contains one test case. Each case occupies a line which contains 4 positive integers:
N1 N2 tag radix
Here N1 and N2 each has no more than 10 digits. A digit is less than its radix and is chosen from the set {0-9, a-z} where 0-9 represent the decimal numbers 0-9, and a-z represent the decimal numbers 10-35.
The last number “radix” is the radix of N1 if “tag” is 1, or of N2 if “tag” is 2.
Output Specification:
For each test case, print in one line the radix of the other number so that the equation N1 = N2 is true. If the equation is impossible, print “Impossible”. If the solution is not unique, output the smallest possible radix.
Sample Input 1:
6 110 1 10
Sample Output 1:
2
Sample Input 2:
1 ab 1 2
Sample Output 2:
Impossible
题目意思:给你两个数N1和N2,并给出来其中一个数的进制作为基数radix,求另一个数的进制是多少时二者相等。第三个数tag如果是1表示radix是N1的进制,求N1的进制;如果是2表示radix是N2的进制,求N1的进制。
解题思路:需要N1和N2各自进制下表示的数相同,需要一个标准,可以都转换成十进制,需要一个函数convert,第一个参数是数值,第二个参数是进制,将这个数值转换为十进制。
数字表示使用[0-9,a-z],所以刚开始想的是另外一个进制的基数范围是1~36,这其实是不对的,基数范围是可以大于这个范围的,最大的情况其实是需要表示的该数的十进制,逐个遍历不是很理想,最佳方式是使用二分法。同时这道题还有一个坑点,如果使用当前进制转换得到的数值比另一个大,说明进制选大了,同时还要注意有可能产生溢出,也就是使用当前进制转换得到的数值小于0,原因也是进制选大了。
#include<iostream> #include<algorithm> #include<string> #include<cstdio> #include<cmath> #define ll long long using namespace std; ll convert(string n,ll radix)//转换为10进制的函数 { ll sum=0; int index=0,temp=0; for(auto it=n.rbegin(); it!=n.rend(); it++) //通过反向迭代器遍历 { if(*it>='0'&&*it<='9') { temp=*it-'0'; } else { temp=*it-'a'+10; } sum+=temp*pow(radix,index++); } return sum; } ll find_radix(string n,ll num) { ll low,mid,high,t; char c='0'; for(auto it=n.begin(); it!=n.end(); it++) { if(*it>c) { c=*it; } } if(c>='0'&&c<='9') { low=c-'0'+1; } else { low=c-'a'+10+1; } high=max(low,num); while(low<=high) { mid=(low+high)/2; t=convert(n,mid); if(t<0||t>num) { high=mid-1; } else if(t==num) { return mid; } else { low=mid+1; } } return -1; } int main() { string n1,n2; ll tag,radix,ans; cin>>n1>>n2>>tag>>radix; if(tag==1) { ans=find_radix(n2,convert(n1,radix)); } else { ans=find_radix(n1,convert(n2,radix)); } if(ans!=-1) { printf("%lld",ans); } else { printf("Impossible"); } return 0; }