1010 Radix

1010 Radix (25 point(s))

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​1​​ and N​2​​, 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

啊呦,这道题目好难哟,做了好久才通过,怎么说呢,这道题看似好像不难,可是后面发现好多易错的坑哟。

先讲题目内容,就是N1,N2为两个数字,radix为进制,tag=1意味着第一个数字的进制为radix,若tag==2,则意味着第二个数字的进制为radix。给出两个数字,以及其中一个数的进制,求第二个数字的进制,以满足两个数数值相同(若答案不唯一,取最小的,这里满足不唯一的情况大概就是只有一位数的时候出现的情况)。

 

思路,1、确定已知的进制是哪一个数字,调整顺序,使得已知的数放在前面(为了方便),

          2、将已知条件的数转为10进制。

          3、利用二分法,求出满足条件的进制

注意点 1、题中给出的是0~9 a~z,但不是意味着进制范围最大是36啊,上限无限大啊!!!!!!好坑哟

            2、细细分析,我们在使用二分法时候,最开始取下限为每一位数的最大值+1,且该数字要大于等于2,上限为(下限和已知数字十进制的最大值)+1。

           3、关于范围问题,题目没有具体限定范围,因此未知是否化为10进制的时候会溢出。这是个问题,我看《算法笔记》书上,它是默认已知数化位10进制时不会超过longlong范围(这个我也不知道怎么得的),但是未知数字在转化为10进制的时候,可能会超出longlong范围!!!这个很关键,搞了半天才晓得。所以在转化的某一步骤中,突然变为负数,说明溢出了。

 

代码如下

#include <cstdio>
#include <cstring>

typedef long long LL;

//数字以字符数组的形式保存,将进制为radix的数转换为10进制返回,
LL GetResult(char a[],LL radix)
{
	LL result=0,cheng=1;
	int i;
	i=strlen(a)-1;
	while(i>=0)
	{
		if(a[i]<'0'||a[i]>'9')
			result+=(a[i]-'a'+10)*cheng;
		else
			result+=(a[i]-'0')*cheng;
		if(result<0)
			return -1;
		cheng*=radix;
		i--;
	}
	return result;

}

//获取数值最大的位数,返回
int findMax(char a[])
{
  int max=0,temp;
  int i=strlen(a)-1;
  while(i>=0)
  {
    if(a[i]<'0'||a[i]>'9')
  			temp=(a[i]-'a')+10;
  		else
  			temp=a[i]-'0';
  	if(temp>max)
  	max=temp;
  	i--;
  }
  return max+1;

}

int main()
{
	char n1[11],n2[11],n[11];
	LL result=0,result_temp;
	int tag,radix;
	LL left=2,right,mid;
	scanf("%s%s%d%d",n1,n2,&tag,&radix);
	if(tag==2)             //交换n1和n2内容
	{
		strcpy(n,n1);
		strcpy(n1,n2);
		strcpy(n2,n);
	}
	result=GetResult(n1,radix);
	left=findMax(n2);
	if(left<2)
		left=2;
	right= (left>result)?left+1:result+1;
	while(left<=right)
	{
		mid=(left+right)/2;
		result_temp=GetResult(n2,mid);
		if(result<result_temp || result_temp <0)  //包含溢出判断,溢出说明太大了
			right=mid-1;
			
		else if(result==result_temp)
		{
			printf("%d",mid);
			return 0;
		}
		else
			left=mid+1;

	}

		
	printf("Impossible");

	

}

在看书以及百度别人的写法时候,发现自己的编码习惯和别人差别还挺大的,还有很多要改善的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值