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.题目
原题不再重复,大意是:
输入四个数:
N1,N2,tag,radix,如果tag为1,则表明N1是radix进制,
反之亦然,N1,N2最多为10位数,且每一位都为09或者az,表示0~35
求是否有一个进制使得在此进制下,未知进制的数和另一个数在十进制下相等。
存在则输出满足条件最小的进制,不存在则Impossible
2.思路
- 步骤1:将已确定进制的数放在N1,未知的为N2,这样可以方便计算
- 步骤2:将N1转换为10进制
-步骤3:二分法找出N2的最小进制(minRadix):将N2由mid进制转为十进制,如果N2>N1,说明当前进制过大,则,high = mid -1,即往左边继续二分;如果N2<N1,说明当前进制过小,则low = mid +1,即往右边继续二分;如果N2==N1,则说明该进制符合要求,但为求最小(题目要求),因此,更新minRadix的值,继续往左,high = mid -1。二分结束时就可判断解是否存在,存在则获得最小的合适进制(midRadix)。
3.注意点
1.暴力枚举会超时
2.minRadix并不会因为每一位只能表示0~35而使得最大36进制,可能超大哦,所以,要把minRadix和存储十进制下的N1,N2的两个变量(num1,num2)都设置成long long 型
3.当minRadix超大时,要小心计算num2时溢出的问题(num2在转换过程中的某一步小于0了),测试点10专门设了这个坑
4.剪枝的方法:在转换N2的累加过程中,不断去判断结果是否大于N1或者结果是否溢出,如果是,则不必再往下计算了,N2在该进制下一定大于N2
5.N2的进制的范围是:最小比N2中的最大一位数字大1;最大不超过N1的值和N2最小进制中大的那个数
#include<iostream>
#include<math.h>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;
/*将radix进制的数转化为十进制的数*/
long long int stonum(string s,long long radix)
{
long long num=0;//用来记录十进制数是多少
long long temp=0;// 用来记录位数
for(int i=s.length()-1;i>=0;i--)
{
if(isalpha(s[i]))
num+=(s[i]-'a'+10)*pow(radix,temp++);
else
num+=(s[i]-'0')*pow(radix,temp++);
}
return num;
}
/*二分搜索法*/
long long int search(long long l,long long r,long long n1,string s/*可以传递string类型*/)
{
while(l<=r)//在可行的范围内
{
long long mid=(l+r)/2,sum=0,temp=0;
sum=stonum(s,mid);//函数调用函数
if(sum==n1)
return mid;
//溢出了,能不剪枝吗!当溢出时sum<0,此时比0x7fffffff还大
if(sum<0)
r=mid-1;
else if(sum<n1) l=mid+1;
else r=mid-1;
}
/*出了可行范围 就GAMEOVER了*/
return -1;
}
int main()
{
string s1,s2,s;
int tag,radix;
long long int n1=0,n2=0;
cin>>s1>>s2>>tag>>radix;
s=tag>1?s2:s1;//找出已知系数的数的底数
n1=stonum(s,radix);//将已知radix的数转化为10进制
s=tag>1?s1:s2;//把s赋上另一个数
/*下面开始去找所求数中所有位数最大的那位,因为所求radix至少比它大*/
long long int max=-1;
for(int i=s.length()-1;i>=0;i--)
{
if(isalpha(s[i])&&s[i]-'a'+10>max)
max=s[i]-'a'+10;
else if(isdigit(s[i])&&s[i]-'0'>max)
max=s[i]-'0';
}
/*找出所求数的radix的下界*/
long long int l=max+1>2?max+1:2;//radix至少是2
/*求出所求数的radix的上界*/
long long int r=n1>l?n1:l;
/*寻找 代求出数 的radix*/
if(search(l,r,n1,s)==-1)
cout<<"Impossible";
else
cout<<search(l,r,n1,s);
return 0;
}
#include <algorithm>
#include <string.h>
#include <cctype>
#include <cmath>
#include <iostream>
using namespace std;
char FindMaxElement(char ch[])
{ /* 寻找字符数组中最大的元素 */
return *max_element(ch, ch+strlen(ch));
}
int charToint(char c)
{ /* 把字符转为数字 */
return isdigit(c) ? c - '0' : c - 'a' + 10;
}
long long transfer(char ch[], long long radix)
{ /* 转换成十进制 */
long long sum = 0;
for (int i = strlen(ch)-1; i >= 0; i--)
sum += charToint(ch[i]) * pow(radix, strlen(ch)-1-i);
return sum;
}
long long check(char ch[], long long num)
{ /* 采用二分法进行寻找 */
long long low = charToint(FindMaxElement(ch))+1, mid; /* 这里下界是ch中最大的字符数值+1 */
long long high = num > low ? num : low;
while (low <= high)
{
mid = (low+high) / 2;
long long aws = transfer(ch, mid);
if (aws < 0 || aws > num)
high = mid - 1;
else if (aws == num)
return mid;
else
low = mid + 1;
}
return -1;
}
int main(int argc, char const *argv[])
{
char N1[11], N2[11];
int tag;
long long r, radix;
cin >> N1 >> N2 >> tag >> radix;
r = tag == 1 ? check(N2, transfer(N1, radix)) : check(N1, transfer(N2, radix));
if (r == -1)
cout << "Impossible";
else
cout << r;
return 0;
}