程序设计基础4 二分A1010

1010 Radix (25)(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

一,我的解法

方法:这道题的解题方法无非是根据两个数组确定进制的上下限然后二分。

我的缺陷:数位的数最大可以去到35,而进制可以取到到2^31-1,肯定超出int,故需要用long long存储,这点没想到。

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
char str1[13];
char str2[13];
int len1;
int len2;
int charge(char c){
	int num;
	if(c>='0'&&c<='9'){
		num=c-'0';
	}
	else{
		num=c-'a'+10;
	}
	return num;
}
int decimal(char a[],int rate,int len){
	int y=0,product=1;
	for(int i=len-1;i>=0;i--){
		y=y+charge(a[i])*product;
		product=product*rate;
	}
	return y;
}
int double_distribution(char a[],int len,int model){
	int l=1,r=36;
	while(l<=r){
		int mid=(l+r)/2;
		if(decimal(a,mid,len)==model) return mid;
		else if(decimal(a,mid,len)<model) l=mid+1;
		else r=mid-1;
	}
	return -1;
}
int main(){
	int m,n,tag,radix;
	int model;
	int j;
	scanf("%s %s %d %d",str1,str2,&tag,&radix);
	len1=strlen(str1);
	len2=strlen(str2);
	if(tag==1){
		model=decimal(str1,radix,len1);
		j = double_distribution(str2,len2,model);
		//printf("%d",model);
	}
	else if(tag==2){
		model=decimal(str2,radix,len2);
		j = double_distribution(str1,len1,model);
		//printf("%d",model);
	}
	if(j>0) printf("%d",j);
	else printf("Impossible");
	return 0;
}

二,正确解法

优点:

1,成功使用了long long存储,并且知道一旦溢出,便可判断为次数大于,用r=mid-1.

2,存储a-z的方式也是很好的,用a-z做下标,若想找到对应的数字直接Map[a[i]]即可,耦合性好。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
LL Map[256];
LL inf=(1LL<<63)-1;
void init(){
	for(char c='0';c<='9';c++){
		Map[c]=c-'0';
	}
	for(char c='a';c<='z';c++){
		Map[c]=c-'a'+10;
	}
}
LL Convertion_ten(char a[],LL radix,LL t){
	LL ans=0;
	int len = strlen(a);
	for(int i=0;i<len;i++){
		ans = ans*radix + Map[a[i]];
		if(ans>t||ans<0) return -1;
	}
		return ans;
} 
int cmp(char a[],LL radix,LL n1){
	LL num = Convertion_ten(a,radix,n1);
	if(num<0) return 1;
	else if(num<n1)  return -1;
	else if(num==n1) return 0;
	else return 1;
}
LL BinarySearch(LL low,LL high,char a[],LL n1){
	LL l = low,r = high;
	while(l<=r){
		LL mid = (l+r)/2; 
	    int assume = cmp(a,mid,n1);
		if(assume==0) return mid;
		else if(assume==-1) l = mid+1;
		else  r=mid-1;
	}
		return -1;
}
int findLargestDigit(char a[]){
	int len = strlen(a);
	int ans = -1;
	for(int i=0;i<len;i++){
		if(Map[a[i]]>ans)
			ans=Map[a[i]];
	}
	return ans+1;
}
int main(){
	init();
	char str1[15];
	char str2[15];
	int tag,radix;
	scanf("%s %s %d %d",str1,str2,&tag,&radix);
	if(tag==2){
		char temp[15];
		strcpy(temp,str1);
		strcpy(str1,str2);
		strcpy(str2,temp);
	}
	LL t = inf;
	LL n1 = Convertion_ten(str1,radix,inf);
	LL low = findLargestDigit(str2);
	LL high = max(low,n1)+1;
//	printf("%lld %lld",low,high);
	LL ans = BinarySearch(low,high,str2,n1);
	if(ans==-1) printf("Impossible\n");
	else printf("%lld\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq2285580599/article/details/81156874