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 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
说实话,这篇代码写的很不让人满意,没有调用任何子函数,所有的过程一股脑都在main 当中,好在思路、结构还不算混乱,只能用注释来弥补了,pat中用到long long int类型的题目多吗?好像不多,但是这道题还真是让人费解,由于算法原因,如果指数空间不够大,利用了int类型,会出现第7个测试的超时的问题,实际上并不是真正的时间不够用,而是int范围的限制使得运行出现了死循环。。。。。。根据测试结果,二分查找貌似是必要的,穷举的话好像数据量有点大,不好说第7个测试点用了什么数据,最坏的话,已知的数是35个z,而未知进制的数是10,穷举的计算量显然让人受不了……
#include<stdio.h>
int main(){
	char *a,*b,aa[10],bb[10];
	char ch,ch_max='0';
	int i=0,j=0,k,p,tag;
	long long low,high,temp,radixa, radixb;
	double result[2]={0,0};//分别存放a和b的十进制结果

	/*下面的两个循环用于得到两个数*/
	while(  (ch=getchar()) != ' '  )
		aa[i++] = ch; //则aa一共有i位
	a=aa;
	while(  (ch=getchar()) != ' '  )
		bb[j++] = ch; //则bb一共有j位
	b=bb;
	scanf("%d",&tag);
	if(tag==2) {    //tag等于2的情况和等于1时没什么区别,无非是前两个数调换了位置,仅此而已
		i^=j^=i^=j;
		a=bb;
		b=aa;
		tag = 1;
	}
	/* 下面是整篇代码的核心部分*/
	if(tag == 1){
		scanf("%I64d",&radixa);
		for(k=0;k<i;k++){
			if(a[k]>='0' && a[k]<='9')
				temp = a[k]-'0';
			else if(a[k]>='a' && a[k]<='z')
				temp = a[k]-'a'+10;
	/*-------------------------------------------------------------*/
			else 
				goto impossible;//给出无效字母	
			if(temp>=radixa)//数据出错,如956,但给出的进制是7,显然不合理
				goto impossible;
	/*----------------------------------------------------------------*/
	/*这段代码删掉也无妨,主要是为了应对测试数据出错的问题,不过显然pat没出这种奇葩问题*/
			result[0] = temp + result[0]*radixa;
		}

		/*找出数字(字母)中最大的,也就是进制可能的最小值*/
		for(p=0;p<j;p++)
			if( (ch=b[p]) > ch_max )//ascii码比较大也就数值比较大
				ch_max = ch;
		if(ch_max-'a'>=0)
			low = ch_max-'a'+10+1;//最大位+1就是最小可能进制
		else	
			low = ch_max-'0'+1;

		high = result[0]>low+1 ? result[0]:low+1;//进制可能的最大值

		/*把b[k]中的数字和字母都转换为其所代表的值,如‘0’->0,'a'->10*/
		for(k=0;k<j;k++){
			if(b[k]>='0' && b[k]<='9')
				b[k] = b[k]-'0';
			else if(b[k]>='a' && b[k]<='z')
				b[k] = b[k]-'a'+10;
		}

		/*二分查找找出合适的radix*/
		while(low<=high){
			result[1] = 0;
			radixb = (low+high)/2;
			for(k=0;k<j;k++)
				result[1] = b[k]+result[1]*radixb;
			if(result[1]>result[0])
				high = radixb-1;
			else if(result[1]<result[0])
				low = radixb+1;
			else	//说明此事已找到radixb使得result[1]==result[0]
				break;
		}
	}
	if(result[1] == result[0])
		printf("%ld",radixb);
	else 
impossible:printf("Impossible");	
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值