PAT 甲级 A1010

1010 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 N​1and N​2​​ , your task is to find the radix of one number while that of the other is given.

输入格式

Each input file contains one test case. Each case occupies a line which contains 4 positive integers:
N1 N2 tag radix
Here N1 and N2each 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.

输出格式

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

总结

  1. 使用二分法不会超时,但二分的上下界得确定。二分的下界low为未知进制的所有数位中的最大数加1,上界为max(low,N1)+1。二分的下界如果简单确定为2,会有两个测试点过不去。如果定为0,会有更多点过不去,佛了。
  2. 进制转化时,long long类型的数照样会发生上溢,因此也要把这种情况加入二分的判断中
  3. 输出的进制需要是尽可能小的进制,因此每次求到一个解都需要比较
  4. 还有一点值得提,当N1和N2都越界时,应该输出radix,但是测试数据里面貌似没有这种情况,为了代码看起来比较少我就判断这种情况。

AC代码

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<ctype.h>
using namespace std;
typedef long long ll;
ll toNum(char c) {
	if (isdigit(c)) {
		return c - '0';
	}
	return c - 'a' + 10;
}
ll toDemical(string a, int r) {
	ll ans = 0;
	for (int i = 0; i < a.size(); i++) {  
	    ans = ans * r + toNum(a[i]);
		if (ans < 0) return -1; //越界
	}
	return ans;
}
int main() {  
	string a, b;
	int tag, radix;
	ll N1, N2;
	cin >> a >> b >> tag >> radix;
	if (tag == 2) {  //a为已经确定进制的数
		swap(a, b);
	}
	N1 = toDemical(a, radix);  //转化为10进制

	ll low = 2, high = max(low, N1) + 1, ans;

	for (int i = 0; i < b.size(); i++)        //算出最低的进制数 
	{
		low = max(low, toNum(b[i]) + 1);
	}

	bool flag = false;
	while (low <= high) {   //二分
		ll mid = (low + high) / 2;
		N2 = toDemical(b, mid);
		if (N2 == -1|| N2 > N1||(int)mid<0) { //过大,或者mid超出int的范围(不过测试数据并没有这种情况)
			high = mid - 1;
		}
		else if (N2 < N1) {
			low = mid + 1;
		}
		else {  //有解,继续查询更小的解
			flag = true;
            ans = mid;
			high = mid - 1;
		}
	}
	if (flag) {
		printf("%lld\n", ans);
	}
	else {
		printf("Impossible\n");
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章