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 <cstdio>

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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值