標籤:style blog color io os 使用 ar for sp
過了一天感覺沒幹什麼,想刷一發題彌補一下,正在考慮去做哪道,室友說去試試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;}
PAT 1010 Radix