PAT A 1010. Radix (25)

本文介绍了一个算法问题,探讨如何判断两个不同进制的正整数是否相等。通过输入两个数及其其中一个数的进制,利用二分查找来高效地找出另一个数能够匹配的进制。文章还详细介绍了实现这一功能的代码逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

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

 

即求1个基数不确定的数是否可以在某个基数下和另一个基数确定的数相等。

直接模拟。

注意点:

1、基数必须大于数中最大的“数字”。

2、转换时必须考虑溢出问题,因为基数稍大一点转换时非常可能溢出。

3、基数范围可以很大,需要二分查找。如999999999(D)、10,后者基数为999999999时是相等的。

 

代码

#include <iostream>
#include <climits>
using namespace std;

int To_dex(char n);	//将一个字符转换为相应的数
int cmp(long long n1,char* n2,long long radix); //将n2按指定的基数radix转换后和n1比较大小

int main()
{
	int tag,r_temp;			//标签,临时数据
	long long radix;		//基
	long long n1=0,n2=0;	//!!!n1表示确定基数的那个数,n2为待测数
	char num[2][11];		//存字符表示的两个数
	int i;

	cin>>num[0]>>num[1];
	cin>>tag>>radix;
	
	for(i=0;i<11;i++)	//获取n1的值
		if(num[tag-1][i]!='\0')
			n1=n1*radix+To_dex(num[tag-1][i]);
		else
			break;

	long long radix_min=2;	//获取最小的radix(基于n2的最大字符);
	for(i=0;i<11;i++)
	{
		if(num[tag%2][i]!='\0')
		{
			r_temp=To_dex(num[tag%2][i])+1;
			if(r_temp>radix_min)
				radix_min=r_temp;
		}
		else
			break;
	}

	int cmp_result;
	long long radix_max=n1+1;	//!!!因为n1可能比n2基数小1,而n2可能表达的最小值也正好为该值
	while(radix_min<=radix_max)	//二分查找
	{
		radix=radix_min+(radix_max-radix_min)/2;
		cmp_result=cmp(n1,num[tag%2],radix);
		if(cmp_result==0)
		{
			cout<<radix;
			return 0;
		}
		else if(cmp_result<0)
			radix_min=radix+1;
		else
			radix_max=radix-1;
	}

	cout<<"Impossible";

	return 0;
}

int To_dex(char n)	//将一个字符转换为相应的数
{
  if(n>='a'&&n<='z')
    return 10+n-'a';
  else
    return 0+n-'0';
}

int cmp(long long n1,char* c2,long long radix)	//将n2按指定的基数radix转换后和n1比较大小
{
	long long n2,n2_last;	//n2,暂存上次的n2
	int i;
	n2=0;
	n2_last=0;
	for(i=0;i<11;i++)
	{
		if(c2[i]!='\0')
		{
			n2_last=n2;
			n2=n2*radix+To_dex(c2[i]);
			if(n2>n1||n2<=n2_last)	//!!!这个溢出处理是不可靠的,需要拿上限的基数分之一比较
				return 1;
		}
		else
			break;
	}
	if(n1==n2)
		return 0;
	else if(n1>n2)
		return -1;
	else 
		return 1;
}


 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值