PAT 1010 Radix

过了一天感觉没干什么,想刷一发题弥补一下,正在考虑去做哪道,室友说去试试PAT 1010,果然当年自己直接跳过了这题,一看这通过率(0.07)有点夸张了。题目是已知一个数,求另外一个数的基数,使得这两个数数值上相等。很自然的考虑到使用二分搜索来确定这个基数,数字表示使用[0-9a-z],这tmd的让人很容易的想到基数的范围就在1~36之间了,艹,基数是可以超过这个范围的,如果没有考虑到这一点,可以得到的一个典型分值就是19分。不过基数在[1, 36]之间的话这个搜索范围太小了,直接暴力遍历也可以,于是闷声不响的扩大范围,总之是坑题,哎没办法,老女人就是爱这样。下面给出代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;

char char2num[128];

int remove_leading_zero(char* str) {
    if (str[0] == ‘\0‘) return 0;
    int ri = 0, wi = 0;
    while (str[ri] == ‘0‘ || str[ri] == ‘+‘ || str[ri] == ‘-‘) ri++;
    int len = 0;
    while ((str[wi++] = str[ri++]) != ‘\0‘) len++;
    if (len == 0) {
        str[0] == ‘0‘;
        str[++len] = ‘\0‘;
    }
    return len;
}

long long value(const char* str, int len, long long radix) {
    long long ret = 0;
    long long r = 1;
    for (int i=len - 1; i>=0; i--) {
        int digit = char2num[str[i]];
        // we should check the number validation
        if (digit >= radix) return -1;
        ret += r * digit;
        r *= radix;
    }
    return ret;
}

int inc_cmp(char* str, int len, long long radix, long long target){
    long long v = 0;
    long long r = 1;

    for (int i=len - 1; i>=0; i--) {
        int digit = char2num[str[i]];
        v += r * digit;
        r *=radix;
        if (v > target) {
            return 1;
        }
    }
    if (v == target) {
        return 0;
    } else {
        return -1;
    }
}

long long binary_search(char* str, int len, long long lo, long long hi, long long target){
    long long mid;
    lo = lo - 1;
    hi = hi + 1;

    while(lo + 1< hi){
        mid = (lo + hi) / 2;
        int res = inc_cmp(str, len, mid, target);
        if(res > 0) {
            hi = mid;
        } else if(res < 0) {
            lo = mid;
        } else {
            return mid;
        }
    }
    return -1;
}

int main() {
    // init char2num lookup table
    for (int i=0; i<10; i++) char2num[‘0‘ + i] = i;
    for (int i=‘a‘; i<=‘z‘; i++) char2num[i] = i - ‘a‘ + 10;

    char num1[16] = {‘\0‘};
    char num2[16] = {‘\0‘};
    char *pnum1 = num1, *pnum2 = num2;
    int tag = 0;
    long long bradix = 0;

    scanf("%s%s%d%ld", num1, num2, &tag, &bradix);

    // we always assure that bradix is the radix of pnum1
    // and pnum2 is which we should guess its radix
    if (tag != 1) {
        pnum1 = num2;
        pnum2 = num1;
    }

    int n1len = remove_leading_zero(pnum1);
    int n2len = remove_leading_zero(pnum2);

    long long n1 = value(pnum1, n1len, bradix);

    bool is_same = !strcmp(pnum1, pnum2);

    if(is_same) {
        if (n1len > 1) {
            // must be same radix, if digits more than one
            printf("%d\n", bradix);
        } else {
            // only one digit, so choose a smallest valid radix
            printf("%d\n", n1 + 1);
        }
        return 0;
    } 

    long long lo = 0;
    for (int i=0; i<n2len; i++) {
        int d = char2num[pnum2[i]];
        if (d + 1> lo) lo = d + 1;
    }

    long long hi = n1 > lo ? n1 : lo;
    int res = binary_search(pnum2, n2len, lo, hi, n1);
    if (res < 0) {
        printf("Impossible\n");
    } else {
        printf("%d", res);
    }

    return 0;
}
时间: 2024-10-29 04:45:03

PAT 1010 Radix的相关文章

PAT 1010. Radix (25)

1010. Radix (25) 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 i

PAT 1010 Radix 进制转换+二分法

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

PAT 1010 Radix (二分)

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 o

1010. Radix (25)——PAT (Advanced Level) Practise

题目信息: 1010. Radix (25) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue 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 b

PAT 1010

1010. Radix (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue 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

1010 Radix(25 分)

1010 Radix(25 分) 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 N?1?? and N?2??, your task is

1010 Radix

1010 Radix 注意点 如111 1 1 10类似情况下,若n为个位数,如果本身比另一个数小,则多少的进制都是没有用的(可能会造成空循环而超时),不过好像没有这么一个测试用例 进制应该比最少数据中的最大的数要大一,如8最少是9进制的数,z最少是36进制的数 注意算法中的超时问题如9999999999 11 1 10很容易超时,注意匹配的算法 如果用c等强类型语言写,注意溢出问题,int类型肯定是不够的 python3代码 def getNum(num, radix): sum = 0 co

PAT 甲级测试题目 -- 1010 Radix

题目链接 题目描述 给你两个数以及其中一个数的基数(进制数),找出另一个数的基数,找不到就输出 Impassible 分析 思路不是很难,基本可以用进制转换加循环判断做,但是有坑... 坑1:上界不是36....上界是确定的那个数的十进制加 1 . 坑2:暴力循环会导致时间超限,用二分法解决 坑3:二分过程中会有数据溢出,得到的负数处理方式和找到较大数处理方式一样,因为溢出的数和题目条件不符,所以可以舍弃. 实现 #include<iostream> #include<string.h&

PAT 甲级 1010 Radix

https://pintia.cn/problem-sets/994805342720868352/problems/994805507225665536 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 fo