1010. Radix (25)
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 10Sample Output 1:
2Sample Input 2:
1 ab 1 2Sample Output 2:
Impossible
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
long long exchang(string s, long long radix) {//把string转化为十进制数,注意可能会overflow,这时候返回的是负值
int i,j;
long long temp;
long long count=0;
for (i = 0; i < s.size(); i++) {
if (s[i] >= '0'&&s[i] <= '9')
temp = s[i] - '0';
else
temp = s[i] - 'a' + 10;
for (j = 0; j < s.size() - i - 1; j++) {
temp *= radix;
}
count += temp;
}
return count;
}
int main() {
long long i;//long long 类型,因为36^10只有longlong类型勉强能装下,但是进制数不止只有36,所以也可能会溢出overflow
long long tag, min_begin;
long long radix;
long long temp, t1;
string N1, N2;
char radix1;
char max = '0';
cin >> N1 >> N2 >> tag >> radix;
if (tag == 2)
swap(N1, N2);
temp = exchang(N1, radix);
for (i = 0; i < N1.size(); i++) {
if (N1[i] > max)
max = N1[i];
}
if (max >= '0'&&max <= '9')
min_begin = max - '0';
else
min_begin = max - 'a' + 10;
if (radix <= min_begin) {
cout << "Impossible" << endl;
return 0;
}
max = '0';
for (i = 0; i < N2.size(); i++) {
if (N2[i] > max)
max = N2[i];
}
if (max >= '0'&&max <= '9')
min_begin = max - '0';
else
min_begin = max - 'a' + 10;
min_begin = min_begin+1;
/*if (temp < 1000) {
for (i = min_begin; i <= 1000; i++) {
if (exchang(N2, i) == temp) {
cout << i << endl;
break;
}
}
if (i == 1001)
cout << "Impossible" << endl;
return 0;
}*/
long long j, k;
long long INF;
INF = temp + 1;
j = min_begin; k = INF;
i = (j + k) / 2;
while (true) { //必须用二分法
i = (j + k) / 2;
t1 = exchang(N2, i);
if (temp < t1||t1<0) {
k = i - 1;
}
else if (temp > t1) {
j = i + 1;
}
else if (t1 == temp) {
printf("%ld\n", (long)i);
return 0;
}
if (j > k) {
cout << "Impossible";
return 0;
}
}
}
感想:
1.这道题我真的是血都做出来了,估计得花了有4个小时,就是有一个点一直答案错误,加大上限的话就会超时,最后是看网上的解答才弄出来的
2.用longlong类型,注意是否有溢出,在计算count的时候可能会溢出
3.二分法,因为值是关于进制数单调递增的,然后二分法的上限必须设置为第一个数加一,因为这样才能保证当数字只有一位的时候取得是最小的解
4.这道题的一些知识点:1.溢出后值是小于零的 2.a>>1相当于a/2 3.二分法注意循环的时候应该是min=mid+1,或者max=mid-1 而不是mid=min或者max,