進制轉換是計算機科學基礎,ACM 競賽中常見變體:大整數進制轉換、負進制、非標準進制(如斐波那契進制)、帶小數點轉換等。NJUPT OJ 1012 為典型大整數任意進制互轉題目。
string toBase(long long n, int base) {
if (n == 0) return "0";
string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string res;
bool neg = n < 0;
if (neg) n = -n;
while (n) {
res.push_back(digits[n % base]);
n /= base;
}
if (neg) res.push_back('-');
reverse(res.begin(), res.end());
return res;
}
long long fromBase(const string &s, int base) {
long long res = 0;
for (char c : s) {
int val = isdigit(c) ? c - '0' : toupper(c) - 'A' + 10;
res = res * base + val;
}
return res;
}
當數字超出 64 位範圍,需用數組/字符串模擬除法與乘法:
res = res * base + digit,用高精度乘法/加法。// 大整數除以小整數,返回商(字符串)和餘數
pair divmod(const string &num, int base) {
string quot;
int rem = 0;
for (char c : num) {
int cur = rem * 10 + (c - '0');
quot.push_back('0' + cur / base);
rem = cur % base;
}
// 去除前導零
size_t pos = quot.find_first_not_of('0');
if (pos == string::npos) quot = "0";
else quot = quot.substr(pos);
return {quot, rem};
}
如基數 -2:餘數必須非負,若餘數 < 0,則 rem += abs(base); quot++。
利用貪心:從最大斐波那契數開始減,對應位置 1,不連續放 1(Zeckendorf 定理)。
string convertBase(string num, int fromBase, int toBase) {
// 1. fromBase -> 十進制 (大整數)
// 2. 十進制 -> toBase (大整數)
// 合併優化:直接在 fromBase 和 toBase 之間轉換,避免中間十進制大數
}
競賽中建議預寫高精度加減乘除模塊,組合出通用進制轉換工具。