您的位置:首页 > 其它

1010. Radix (25)

2014-11-10 18:45 176 查看
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


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

/*
* 给两个数a, b,a的进制已给出,b为多少进制的时候会和a相等,也可能永远不可能相等
*/

int Num(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
else
return c - 'a' + 10;
}
long long getRadix(char a[], char b[], int radix)
{
long long aSum = 0;
int i = 0;
while (a[i])
aSum = Num(a[i++]) + aSum * radix;
long long bSum;
int size = strlen(b);
long long r = 1;//表示b的最小进制
for (i = 0; i < size; ++i)
{
if (Num(b[i]) > r)
r = Num(b[i]);
}
++r;
if (size == 1)
{
if (aSum == Num(b[0]))
return r;//return Num(b[0]) == 0 ? 2 : Num(b[0]) + 1; //这里返回Num(b[0]) + 1也可以, 因为Num(b[0])依题意是不会等于0的
}
else
{
//折半查找
long long mid;
long long high = aSum;
while (r <= high)
{
bSum = 0;
mid = (r + high) / 2;
/*for (i = 0; i < size &&bSum >= 0 &&  bSum < aSum; ++i)
bSum = bSum * mid + Num(b[i]); //bSum可能溢出
if (i == size)
{
if (aSum == bSum)
return mid;
else if (aSum < bSum)
high = mid - 1;
else
r = mid + 1;
}
else
high = mid - 1;
*/
<span style="white-space:pre">			</span>for (int i = 0; i < size && bSum >= 0; ++i)
<span style="white-space:pre">				</span>bSum = bSum * mid + Num(b[i]);
<span style="white-space:pre">			</span><pre name="code" class="cpp" style="color: rgb(51, 51, 51); font-size: 13px; line-height: 20px;"><span style="white-space:pre">			</span>if (aSum == bSum)
return mid;
else if (aSum < bSum)
high = mid - 1;
else
r = mid + 1;

}
}
/*
else if (size == 2)
{
if (Num(b[0]) * r + Num(b[1]) <= aSum && (aSum - Num(b[1])) % Num(b[0]) == 0)
return (aSum - Num(b[1])) / Num(b[0]);
}
else
{

while (r <= aSum) //这种方法虽然过了,但其时间复杂度是否符合题目要求是有待考查的, 这里可以通过折半查找的方法来减少时间复杂度, 进制一定在r至aSum之间
{
bSum = 0;
i = 0;
while (i < size && bSum < aSum)
bSum = bSum * r + Num(b[i++]);
if (i == size && bSum == aSum)
return r;
++r;
}
}*/
return -1;
}
int main(void)
{
char a[11], b[11]; //a,b范围0-35^10,超过int表示范围
int tag, radix; // radix取值范围0-9 a-z(10 - 35) tag = 1,radix表示a的进制,tag = 2,radix表示b的进制

scanf("%s%s%d%d", &a, &b, &tag, &radix);
long long r;
if (tag == 1)
r = getRadix(a, b, radix);
else
r = getRadix(b, a, radix);
r == -1 ? printf("Impossible\n"):printf("%lld\n", r);
return 0;

}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: