PAT习题解:1010. Radix (25)

题目链接:http://www.patest.cn/contests/pat-a-practise/1010

这道题主要考察进制转换和二分查找,坑的地方主要在大数溢出上,需要使用long long类型。搞定以后挺爽的,哈哈。

题目大意为,给定数a和数b以及数a的进制,求数b的进制,使数a与数b相等。

策略是采取二分查找法,确定的进制上下界中,查找一个进制,使其满足等式。

进制的下界容易确定,必然为数b中最大符号代表的数加上1。进制的上界为数a和数b最大符号代表的数的最大值加上1。(进制必然小于数a,因为比数a大的话,数b必然比数a大;如果数a小于数b中的最大符号,数a必然比数b小,肯定找不到这一进制。)

此进制有可能很大,所以需要采用long long类型。

比较时,有可能提前确定出两数在当前进制下的大小。

#define _CRT_SECURE_NO_WARNINGS
#include 

typedef long long ll;

int char2int(char c)
{
	if (c >= '0' && c <= '9')
	{
		return c - '0';
	}
	else if (c >= 'a' && c <= 'z')
	{
		return c - 'a' + 10;
	}
	else
	{
		return -1;
	}
}

ll str2ll(char num[], ll radix)
{
	ll sum = 0;
	for (int i = 0; num[i] != '\0'; i++)
	{
		sum = sum * radix + char2int(num[i]);
	}
	return sum;
}

int findSmallestRadix(char num[])
{
	int max = 0;
	for (int i = 0; num[i] != '\0'; i++)
	{
		if (max < char2int(num[i]))
		{
			max = char2int(num[i]);
		}
	}
	return max + 1;
}

int compare(ll n1, char n2[], ll radix)
{
	ll sum = 0;
	for (int i = 0; n2[i] != '\0'; i++)
	{
		sum = sum * radix + char2int(n2[i]);
		if (sum > n1)
		{
			return 1;
		}
	}
	if (sum > n1)
	{
		return 1;
	}
	else if (sum < n1)
	{
		return -1;
	}
	else
	{
		return 0;
	}

}
ll biSearch(ll n1, char n2[])
{
	ll l = (ll)findSmallestRadix(n2);
	ll r = (n1 > l) ? n1 + 1 : l + 1;
	ll m;
	while (l < r )
	{
		m = (l + r) / 2;
		if (compare(n1, n2, m) == 1)
		{
			r = m;
		}
		else if (compare(n1, n2, m) == -1)
		{
			l = m;
		}
		else
		{
			return m;
		}
	}
	return -1;
}
int main()
{
	char n1[11];
	char n2[11];
	char tag;
	ll radix;
	scanf("%s %s %c %lld", n1, n2, &tag, &radix);
	ll r;
	switch (tag)
	{
		case '1':
			r = biSearch(str2ll(n1,radix), n2);
			break;
		case '2':
			r = biSearch(str2ll(n2, radix), n1);
			break;
	}
	if (r == -1)
	{
		printf("Impossible");
	}
	else
	{
		printf("%lld", r);
	}
	return 0;
}



你可能感兴趣的:(数据结构与算法)