【ACWing】124. 数的进制转换

题目地址:

https://www.acwing.com/problem/content/description/126/

编写一个程序,可以实现将一个数字由一个进制转换为另一个进制。这里有 62 62 62个不同数位 0 − 9 , A − Z , a − z {0−9,A−Z,a−z} 09,AZ,az

输入格式:
第一行输入一个整数,代表接下来的行数。
接下来每一行都包含三个数字,首先是输入进制(十进制表示),然后是输出进制(十进制表示),最后是用输入进制表示的输入数字,数字之间用空格隔开。
输入进制和输出进制都在 2 2 2 62 62 62的范围之内。
(在十进制下) A = 10 , B = 11 , … , Z = 35 , a = 36 , b = 37 , … , z = 61 A=10,B=11,…,Z=35,a=36,b=37,…,z=61 A=10B=11Z=35a=36b=37z=61 ( 0 − 9 0−9 09仍然表示 0 − 9 0−9 09)。

输出格式:
对于每一组进制转换,程序的输出都由三行构成。
第一行包含两个数字,首先是输入进制(十进制表示),然后是用输入进制表示的输入数字。
第二行包含两个数字,首先是输出进制(十进制表示),然后是用输出进制表示的输入数字。
第三行为空白行。
同一行内数字用空格隔开。

可以先将输入按十进制的方式存入一个vector<int>,从高位到低位存。需要注意的是,并不需要真的将输入转为十进制再存,每一位直接存 0 ∼ 62 0\sim 62 062的数即可。例如,如果输入是ABC,那直接存为 { 10 , 11 , 12 } \{10,11,12\} {10,11,12}即可,如果输入进制是 p p p,则 10 p 2 + 11 p + 12 10p^2+11p+12 10p2+11p+12就是其十进制的真实数字。设输出进制是 q q q,本质上本题就是要让输入对 q q q做若干次带余除法,直到被除数变为 0 0 0,则余数的倒序即为所求。代码如下:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int ain, aout;

char get(int x) {
  if (0 <= x && x < 10)
    return '0' + x;
  else if (10 <= x && x < 36)
    return x - 10 + 'A';
  else
    return x - 36 + 'a';
}

// 让a表示的数对b做带余除法,商重新存入a,余数存入r
void div(vector<int>& a, int b, int& r) {
  vector<int> c;
  r = 0;
  for (int i = 0; i < a.size(); i++) {
    r = r * ain + a[i];
    c.push_back(r / b);
    r %= b;
  }

  // 将商的开头0全去掉。如果商是0的话,直接置a为空
  int idx = 0;
  while (idx < c.size() && !c[idx]) idx++;
  a = vector<int>(c.begin() + idx, c.end());
}

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

  while (T--) {
    string s;
    scanf("%d%d", &ain, &aout);
    cin >> s;

    vector<int> a;
    for (int i = 0; i < s.size(); i++) {
      if ('0' <= s[i] && s[i] <= '9')
        a.push_back(s[i] - '0');
      else if ('A' <= s[i] && s[i] <= 'Z')
        a.push_back(s[i] - 'A' + 10);
      else
        a.push_back(s[i] - 'a' + 36);
    }

    cout << ain << " " << s << endl;
    cout << aout << " ";

    string res;
    int r;
    // 只要商不是0,就进行循环
    while (a.size()) {
      div(a, aout, r);
      res += get(r);
    }
    reverse(res.begin(), res.end());
    cout << res << endl;
    puts("");
  }
}

时空复杂度取决于具体输入,只需注意向量 a a a表示的数字会以对数的速度变小,所以时间是很快的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值