AcWing 数的进制转化

 

主要用到一个高精度除法.

将一个数字(不管是什么进制)转化为x进制表示,只需要不停地将该数字除以x直到结果为0,将所得的一系列余数按原序排列在一起即得结果.因为:

例如将十进制下12345转化为4进制,由于:

12345=3x46+0x45+0x44+0x43+3x42+2x41+1x40.

每当除以4,除最后一项外,4的指数都减一,最后一项即为余数.

得3000321.

这个规律不论是从小的进制到大的进制还是反过来都是正确的.非10进制的高精度除法只需要稍微修改一下.

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

char A[1010];
int A_int[1010], ans[1010], idx;
int t, from, to;

int div1(int x, int l) {
    int tmp[1010];
    A_int[0] = 0;

    for (int i = l; i >= 1; i--) {
        tmp[i] = A_int[i] / x;
        A_int[i - 1] += (A_int[i] % x) * from;
    }
    while (!tmp[l] && l) l--;
    for (int i = l; i >= 1; i--) A_int[i] = tmp[i];

    return l;
}

int main() {
    scanf("%d", &t);

    while (t--) {
        scanf("%d%d%s", &from, &to, A);

        idx = 0;
        int len = strlen(A);
        for (int i = len - 1; i >= 0; i--) {  // turn A to A_int
            if (A[i] >= '0' && A[i] <= '9')
                A_int[len - i] = A[i] - '0';
            else if (A[i] >= 'A' && A[i] <= 'Z')
                A_int[len - i] = A[i] - 'A' + 10;
            else if (A[i] >= 'a' && A[i] <= 'z')
                A_int[len - i] = A[i] - 'a' + 36;
        }

        while (len = div1(to, len)) ans[++idx] = A_int[0] / from;
        ans[++idx] = A_int[0] / from;

        printf("%d %s
%d ", from, A, to);
        for (int i = idx; i >= 1; i--) {
            if (ans[i] >= 0 && ans[i] < 10)
                printf("%d", ans[i]);
            else if (ans[i] >= 10 && ans[i] <= 35)
                printf("%c", ans[i] + 'A' - 10);
            else if (ans[i] >= 36 && ans[i] <= 61)
                printf("%c", ans[i] + 'a' - 36);
        }
        puts("
");
    }

    return 0;
}
AC Code

 这是一道ICPC New York的真题.

原文地址:https://www.cnblogs.com/Gaomez/p/14206962.html