1.题目
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
2.题目分析
开始用正常思路先将一个转为10进制,然后不停转换为其它进制与n2比较,结果测试点 7、10错误
之后得知存在long long溢出以及二分问题,于是改进
3.代码
原版本(测试点7 10 错误)
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
long long changea(string c,int m)
{
long long num = 0;
for (int i = 0; i < c.length(); i++)
{
if (islower(c[i])) num += (c[i] - 'a' + 10) * pow(m, c.length() - 1 - i); //如果是字母的话就+10,因为a代表10
else if (isupper(c[i])) num += (c[i] - 'A' + 10)*pow(m, c.length() - 1 - i);
else if (isdigit(c[i]))num += (c[i] - '0')*pow(m, c.length() - 1 - i);//如果是数字就直接乘
}
return num;
}
string changeb(long long num,int n)
{
string answer = "";
int out[100];
int s = 0;
while (num > 0)
{
out[s++] = num%n;
num /= n;
}
if (n <= 9)//将变为的进制<=9
{
for (int i = s - 1; i >= 0; i--)
answer += (out[i] + '0');
}
else
{
for (int i = s - 1; i >= 0; i--)
{
if (out[i] >= 10)answer += (out[i] - 10 + 'a');
else answer += (out[i] + '0');
}
}
return answer;
}
int main()
{
string n1, n2;
long long tag, radix;
cin >> n1 >> n2 >> tag >> radix;
if (tag == 2)
swap(n1, n2);
long long num = changea(n1, radix);
for (int i = 2; i < 10000; i++)
{
string temp = changeb(num, i);
if (temp == n2) { printf("%lld", i); return 0; }
}
printf("Impossible
");
}
改进:
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int Alpha2int(char c) { //数字转换
if (int(c) >= int('0') && int(c) <= int('9')) {
return (int(c) - 48);
}
else
return int(c) - 87;
}
long long changea(string c,int m)
{
long long num = 0;
for (int i = 0; i < c.length(); i++)
{
if (islower(c[i])) num += (c[i] - 'a' + 10) * pow(m, c.length() - 1 - i); //如果是字母的话就+10,因为a代表10
else if (isupper(c[i])) num += (c[i] - 'A' + 10)*pow(m, c.length() - 1 - i);
else if (isdigit(c[i]))num += (c[i] - '0')*pow(m, c.length() - 1 - i);//如果是数字就直接乘
if (num < 0)return -1;
}
return num;
}
long long changeb(long long start,long long end,long long num ,string n2)
{
long long mid = (start + end) / 2;
long long temp = changea(n2, mid);
long long result = -1;
if (start <= end)
{
if (temp == -1 || temp > num)
{//溢出减少Radix
result = changeb(start, mid - 1, num, n2);
}
else if (temp < num)
{
result = changeb(mid + 1, end, num, n2);
}
else
{
result = mid;
}
}
return result;
}
int main()
{
string n1, n2;
long long tag, radix;
cin >> n1 >> n2 >> tag >> radix;
if (tag == 2)
swap(n1, n2);
long long num = changea(n1, radix);
long long max = num + 1;
long long min = 2;
for (int i = 0; i < n2.size(); i++)
{
if (Alpha2int(n2[i]) >= min)
min = Alpha2int(n2[i]) + 1; //要加1
}
long long result = changeb(min, max,num,n2);
if (result !=-1) { printf("%lld", result); return 0; }
printf("Impossible
");
}