PAT A1010 Radix (25)的解题报告

这题真的是一道神题呀,通过率0.08

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

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最小进制中大的那个数

4.代码

#include
#include
#include
using namespace std;

char n[2][11];
int getbiggist(char n[], int lens)//得到N2中最大的一位数字
{
    int biggest = -1;
    int temp = 0;
    for (int i = 0; i < lens; i++)
    {
        if (n[i] <= '9'&&n[i] >= '0')
        {
            temp = n[i] - '0';
        }
        else
        {
            temp = n[i] - 'a' + 10;
        }
        if (temp > biggest)
        {
            biggest = temp;
        }
    }
    return biggest;
}
int main()
{
    int tag;
    int radix;

    long long num[2] = { 0 };
    scanf("%s", n[0]);
    scanf("%s", n[1]);
    scanf("%d%d", &tag, &radix);
    if (tag == 2)
        swap(n[0], n[1]);
    for (int i = 0; i < strlen(n[0]); i++)//把N1转为10进制存起来
    {
        if (n[0][i] <= '9'&&n[0][i] >= '0')
        {

            num[0] = num[0] * radix + (n[0][i] - '0');
        }
        else
        {
            num[0] = num[0] * radix + (n[0][i] - 'a' + 10);
        }
    }

    long long  low= getbiggist(n[1], strlen(n[1])) + 1;
    long long high = max(num[0] + 1, (long long)low);
    long long minRadix = high + 1;
    long mid = 0;
    int i = 0;
    while (high >= low)
    {
        mid = (high + low) / 2;
        num[1] = 0;
        for (i = 0; i < strlen(n[1]) && num[1]= 0; i++)
        {
            if (n[1][i] <= '9'&&n[1][i] >= '0')
            {
                num[1] = num[1] * mid + (n[1][i] - '0');
            }
            else
            {
                num[1] = num[1] * mid + (n[1][i] - 'a' + 10);
            }
        }
        if (i == strlen(n[1]) && num[1] == num[0])
        {
            minRadix = mid;//更新minRadix的值
            high = mid - 1;
        }
        else
        {
            if (num[1] >= num[0] || num[1] <= 0)
                high = mid - 1;
            else
                low = mid + 1;
        }
    }
    if (minRadix != max(num[0] + 1, (long long)smallest) + 1)
        printf("%lld", minRadix );
    else
        printf("Impossible\n");
    return 0;
}



一件无聊的小事

无聊玩了一下,测试点14,17,18,19,2的答案是impossible,测试点3,4,5的答案是38,测试点10要考虑N2转换过程中溢出问题。。。。唔,那就是说我直接输出printf("Impossible\n");也可以拿个7分, (-_-!!)

你可能感兴趣的:(PAT A1010 Radix (25)的解题报告)