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
andN2
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, anda
-z
represent the decimal numbers 10-35. The last numberradix
is the radix ofN1
iftag
is 1, or ofN2
iftag
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, printImpossible
. 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.先把tag的那个数转化为10进制。
2.利用二分法查找可能的进制。
#include<bits/stdc++.h>
using namespace std;
int main()
{
char str1[11],str2[11];
long long int b1=0,b2=0,low=0,up=0,mid=0,digit=0,tag,radix,m,n,max=0;
cin>>str1>>str2>>tag>>radix;
m=strlen(str1);
n=strlen(str2);
if(tag==1){
for(int i=0;i<m;i++){
b1+=((isdigit(str1[i])?str1[i]-'0':str1[i]-'a'+10)*pow(radix,(m-1-i)));
}
}
else if(tag==2){
for(int i=0;i<n;i++){
b2+=((isdigit(str2[i])?str2[i]-'0':str2[i]-'a'+10)*pow(radix,(n-1-i)));
}
}
//进制转化
if(tag==1){
for(int i=0;i<n;i++){
if(max<(isdigit(str2[i])?str2[i]-'0':str2[i]-'a'+10)) max=(isdigit(str2[i])?str2[i]-'0':str2[i]-'a'+10);
}
//求出下界
low=max+1;
up=b1;
if(up<low){
printf("Impossible");
return 0;
}
while(1){
mid=(low+up)/2;
b2=0;
for(int i=0;i<n;i++) b2+=((isdigit(str2[i])?str2[i]-'0':str2[i]-'a'+10)*pow(mid,(n-1-i)));
if(b2>b1) up=mid;
else if(b2<b1) low=mid+1;
else if(b1==b2){
printf("%lld",mid);
break;
}
if(low==mid){
printf("Impossible");
break;
}
}
}
else if(tag==2){
for(int i=0;i<m;i++){
if(max<(isdigit(str1[i])?str1[i]-'0':str1[i]-'a'+10)) max=(isdigit(str1[i])?str1[i]-'0':str1[i]-'a'+10);
}
//求出下界
low=max+1;
up=b2;
if(up<low){
printf("Impossible");
return 0;
}
while(1){
mid=(low+up)/2;
b1=0;
for(int i=0;i<m;i++) b1+=((isdigit(str1[i])?str1[i]-'0':str1[i]-'a'+10)*pow(mid,(m-1-i)));
if(b1>b2) up=mid;
else if(b1<b2) low=mid+1;
else if(b1==b2){
printf("%lld",mid);
break;
}
if(low==mid){
printf("Impossible");
break;
}
}
}
return 0;
}
不对。。。
注意到的坑:
1.pow的返回值是double,存在误差,在数小的情况下是可以的 ,可是在这种很大的数的情况下是行不通的,所以还得老老实实自己写函数。
2.有一个判断
再试试
#include<bits/stdc++.h>
using namespace std;
long long int max(long long int a,long long int b)
{
return(a>b?a:b);
}
int main()
{
char str1[11],str2[11];
long long int b1=0,b2=0,low=0,up=0,mid=0,digit=0,tag,radix,m,n,maxn=0;
cin>>str1>>str2>>tag>>radix;
m=strlen(str1);
n=strlen(str2);
if(tag==1){
for(int i=0;i<m;i++){
b1+=((isdigit(str1[i])?str1[i]-'0':str1[i]-'a'+10)*pow(radix,(m-1-i)));
}
}
else if(tag==2){
for(int i=0;i<n;i++){
b2+=((isdigit(str2[i])?str2[i]-'0':str2[i]-'a'+10)*pow(radix,(n-1-i)));
}
}
//进制转化
if(tag==1){
for(int i=0;i<n;i++){
if(maxn<(isdigit(str2[i])?str2[i]-'0':str2[i]-'a'+10)) maxn=(isdigit(str2[i])?str2[i]-'0':str2[i]-'a'+10);
}
//求出下界
low=maxn+1;
up=max(b1,low);
while(1){
mid=(low+up)/2;
b2=0;
for(int i=0;i<n;i++) b2+=((isdigit(str2[i])?str2[i]-'0':str2[i]-'a'+10)*pow(mid,(n-1-i)));
if(b2>b1) up=mid;
else if(b2<b1) low=mid+1;
else if(b1==b2){
printf("%lld",mid);
break;
}
if(low==mid){
printf("Impossible");
break;
}
}
}
else if(tag==2){
for(int i=0;i<m;i++){
if(maxn<(isdigit(str1[i])?str1[i]-'0':str1[i]-'a'+10)) maxn=(isdigit(str1[i])?str1[i]-'0':str1[i]-'a'+10);
}
//求出下界
low=maxn+1;
up=max(low,b2);
while(1){
mid=(low+up)/2;
b1=0;
for(int i=0;i<m;i++) b1+=((isdigit(str1[i])?str1[i]-'0':str1[i]-'a'+10)*pow(mid,(m-1-i)));
if(b1>b2) up=mid;
else if(b1<b2) low=mid+1;
else if(b1==b2){
printf("%lld",mid);
break;
}
if(low==mid){
printf("Impossible");
break;
}
}
}
return 0;
}
就多对了1分。。。。