题目
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;
}