文章目录
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
一、题干大意![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/6e985271af18706de1214beffee0a518.png#pic_center)
给出两个字符串和其中一个字符串的进制,求出另一个字符串的进制,使两者的值相等。最后输出求出的进制,如果不存在这种进制就输出 “Impossible”
二、题解要点
- 两个函数,一个用来进行进制转化,也就是把任意进制的字符串转化为十进制的数。另一个用二分法求出进制。
- 一定要注意:在二分法求进制的过程中,求出的进制是有可能上溢的,如果不解决就只能拿15分。
三、具体实现
/**
*@Author:hhzheng
*@Date:2023/2/6 10:58
*@Filename:PAT甲级1010 Radix
*/
#include<iostream>
#include <string>
#include <cmath>
#include <cctype>
#include <algorithm>
using namespace std;
/**
* 输入一个字符串、一个数(表示进制) 将这个字符串转换为该十进制的数
* @param n
* @param radix
* @return
*/
long long turnDecimal(string n, long long radix) {
long long theResult = 0;
for (int i = n.size() - 1; i >= 0; --i) {
if (n.at(i) >= '0' && n.at(i) <= '9') {
theResult += (n.at(i) - '0') * pow(radix, n.size() - i - 1);
}
if (n.at(i) >= 'a' && n.at(i) <= 'z') {
theResult += (n.at(i) - 'a' + 10) * pow(radix, n.size() - i - 1);
}
}
return theResult;
}
/**
* 用二分法求出正确的进制 如果不存在返回-1
* @param n
* @param s
* @return
*/
long long getRadix(long long n, string s) {
char it = *max_element(s.begin(), s.end());
long long low = (isdigit(it) ? it - '0': it - 'a' + 10) + 1; //找到可能的最小的进制
long long high = max(n, low); //找到最大的可能的进制,比如说 1 1 1 10 这种情况就不能high = n了
while (low <= high) {
long long mid = (low + high) / 2;
long long temp = turnDecimal(s, mid);
if (temp < 0 ||temp > n) { //一定要有temp < 0,因为在进制转化的时候有可能会上溢
high = mid - 1;
} else if (temp == n) {
return mid;
} else {
low = mid + 1;
}
}
return -1;
}
int main() {
string n1, n2;
long long number1, number2, radix,answerRadix;
int tag;
cin >> n1 >> n2 >> tag >> radix;
if (tag == 1) {
number1 = turnDecimal(n1, radix);
answerRadix = getRadix(number1,n2);
} else {
number2 = turnDecimal(n2, radix);
answerRadix = getRadix(number2,n1);
}
if (answerRadix != -1){
cout << answerRadix;
}else{
cout <<"Impossible";
}
return 0;
}
总结
全网的写法思路基本差不多,决定成败的就是在如何这个进制的上溢。