PAT (Advanced Level) Practice — 1010 Radix (25 分)

题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805507225665536

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 tagis 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,tag和进制r,如果tag=1,说明n1是r进制数,求n2在几进制的情况下与n1相等。如果tag=2,说明n2是r进制数,求n1在几进制的情况下与n2相等。

:思路  题解一般用的是二分查找法,水水说如果这样做他很难确定上界是多少,然后就用的特判来避免的超时。

首先,这两个数字都是以字符形式输入的,len1表示未知进制数的长度,len2表示已给出进制数的长度。将各个位上的字符转化为数字。

  • 比较未知进制数的各个位上数字并求出最大值st,也就是查询几进制能满足相等条件 这个进制的下界。
  • 将已知r进制数转为10进制数ans,用于比较。
  • 将进制从st开始跑,将 i 进制数转十进制的结果ans1 并与ans进行比较,如果相等就输出 i 进制,如果大于输出 Impossible。

但是这样做会超时,可以想一下如果已知进制的数字转为十进制是10000000000,未知是100,那么循环跑的最大进制是100000,时间复杂度是根号n,如果未知是10,那么循环的最大进制是10000000000,时间复杂度是n。

避免超时的方式是特判:未知进制数是1位和两位的情况

  • 如果未知进制数是一位,无论几进制均是其本身,只需比较ans与一位未知进制数。
  • 如果未知进制数是两位,由于最末位数字不影响比较,那么需判断首位数字c[0]与ans(ans=ans-未知进制数最末位上的数)能否组成倍数关系,其倍数也就是进制数。例:已知数字的十进制为11,未知进制数是32(减掉最末位11→9、9/3=3 但是三进制中最大数字为2,所有不可能相等);再例如:十进制为11,未知进制是23(减掉最末位11→8、8/2=4并且2和3均小于4,故23在4进制的条件下等于11)
#include<iostream>
#include<cstring>
using namespace std;
int main(){
	char a[11],b[11];
	long long tag,r;
	long long c[11];
	cin>>a>>b>>tag>>r;
	long long st=-1;
	int len1,len2;//让len1存未知进制数的长度
	long long ans=0;
	if(tag==1){
		len1=strlen(b);
		len2=strlen(a);
		for(int i=0;i<len1;i++){
			if(b[i]>='0'&&b[i]<='9'){
				c[i]=b[i]-'0';
			}else{
				c[i]=b[i]-'a'+10;
			}
			st=max(st,c[i]);
		}
		long long t;
		long long k=1;
		for(int i=len2-1;i>=0;i--){
			if(a[i]>='0'&&a[i]<='9'){
				t=a[i]-'0';
			}else{
				t=a[i]-'a'+10;
			}
			ans+=t*k;
			k*=r;//r进制转10进制 
		}
	}else{
		len1=strlen(a);
		len2=strlen(b);
		for(int i=0;i<len1;i++){
			if(a[i]>='0'&&a[i]<='9'){
				c[i]=a[i]-'0';
			}else{
				c[i]=a[i]-'a'+10;
			}
			st=max(st,c[i]);
		}
		long long t;
		long long k=1;
		for(int i=len2-1;i>=0;i--){
			if(b[i]>='0'&&b[i]<='9'){
				t=b[i]-'0';
			}else{
				t=b[i]-'a'+10;
			}
			ans+=t*k;
			k*=r;//r进制转10进制 
		}
	} 
	//特判未知进位数为一位和两位,否则会超时。 
	if(len1==1){
		if(c[0]!=ans){
			cout<<"Impossible"<<endl;
		} else{
			cout<<st+1<<endl;
		}
		return 0;
	}
	if(len1==2){
		ans=ans-c[1];
		if(ans%c[0]!=0){
			cout<<"Impossible"<<endl;
		}else{
			long long mm=ans/c[0];
			if(mm>c[0]&&mm>c[1]){
				cout<<mm<<endl;
			}else{
				cout<<"Impossible"<<endl;	
			}
		}
		return 0;
	}
	//进制从未知数的最大一位上的数字+1开始跑 
	for(long long i=st+1;;i++){
		long long ans1=0;
		long long k1=1;
		for(int j=len1-1;j>=0;j--){
			ans1+=c[j]*k1;
			k1*=i;
		}
		if(ans1==ans){
			cout<<i<<endl;
			break;
		} else if(ans1>ans){
			cout<<"Impossible"<<endl;
			break;
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值