算法竞赛进阶指南0x10练习10:进制转换

原题链接

编写一个程序,可以实现将一个数字由一个进制转换为另一个进制。

这里有 62 个不同数位 {0−9,A−Z,a−z}。

输入格式

第一行输入一个整数,代表接下来的行数。

接下来每一行都包含三个数字,首先是输入进制(十进制表示),然后是输出进制(十进制表示),最后是用输入进制表示的输入数字,数字之间用空格隔开。

输入进制和输出进制都在 2 到 62 的范围之内。

(在十进制下)A=10,B=11,…,Z=35,a=36,b=37,…,z=61(0−9 仍然表示 0−9)。

输出格式

对于每一组进制转换,程序的输出都由三行构成。

第一行包含两个数字,首先是输入进制(十进制表示),然后是用输入进制表示的输入数字。

第二行包含两个数字,首先是输出进制(十进制表示),然后是用输出进制表示的输入数字。

第三行为空白行。

同一行内数字用空格隔开。

输入样例:

8
62 2 abcdefghiz
10 16 1234567890123456789012345678901234567890
16 35 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
35 23 333YMHOUE8JPLT7OX6K9FYCQ8A
23 49 946B9AA02MI37E3D3MMJ4G7BL2F05
49 61 1VbDkSIMJL3JjRgAdlUfcaWj
61 5 dl9MDSWqwHjDnToKcsWE1S
5 10 42104444441001414401221302402201233340311104212022133030

输出样例:

62 abcdefghiz
2 11011100000100010111110010010110011111001001100011010010001

10 1234567890123456789012345678901234567890
16 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2

16 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
35 333YMHOUE8JPLT7OX6K9FYCQ8A

35 333YMHOUE8JPLT7OX6K9FYCQ8A
23 946B9AA02MI37E3D3MMJ4G7BL2F05

23 946B9AA02MI37E3D3MMJ4G7BL2F05
49 1VbDkSIMJL3JjRgAdlUfcaWj

49 1VbDkSIMJL3JjRgAdlUfcaWj
61 dl9MDSWqwHjDnToKcsWE1S

61 dl9MDSWqwHjDnToKcsWE1S
5 42104444441001414401221302402201233340311104212022133030

5 42104444441001414401221302402201233340311104212022133030
10 1234567890123456789012345678901234567890

 题意:将某个进制的数转换成另一个进制的数;

解法及思路:(要用到高精度)

一般的解法是将输入的进制数转换成10进制数,再将10进制数转换成另一个进制的数;

这里讲另一种解法,秦九绍进制转换(y总好像是这样说的,虽然我没搜到):

例如:将4进制的123转换成5进制的数,将1除以5,结果为0,余1,

再(1*4+2)除以5,结果为1,余1,再将(1*4+3)除以5,结果为1,余2;

则2表示4进制123在5进制下的最低位,11(上次除的结果),

再重复上述操作,结果为1,余0,再将1(上次除的结果)除以5,结果为0,余1;

所以102表示123在5进制下的数字; (图来自y总讲解)

 假设输入进制为a,输出进制为b,xi表示输入的数的第i位,则运算规则为xn/b;

记录结果,(余数*a+x(n-1)) /b,记录结果,一直到不能除了;

最后的余数就是b进制下的第0位,上述除的结果之和去掉前导0再重复上述操作,

得到余数,为b进制的第1位,以此类推,直到除的结果为0;

 (图片来自y总),看不懂的可以直接看   y总视频

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--){
        int a,b;
        string a_s;//输入的字符串a进制数
        vector<int>number;//反转存储a进制数每一位转换为10进制数
        cin>>a>>b>>a_s;
        for(int i=a_s.length()-1;i>=0;--i){//输入的a_s第一位表示的是高位,为了第一位存储低位,须反转存储;
            if(a_s[i]>='0'&&a_s[i]<='9') number.push_back(a_s[i]-'0');
            else if(a_s[i]>='A'&&a_s[i]<='Z') number.push_back(a_s[i]-'A'+10);
            else number.push_back(a_s[i]-'a'+36);
            }
        vector<int>res;//存储b进制的每一位,
        while(number.size()){//进行秦九绍循环除法;
            int temp=0;//余数
            for(int i=number.size()-1;i>=0;--i){
                number[i]+=temp*a;
                temp=number[i]%b;
                number[i]/=b;
            }//每一次的最后余数temp表示b进制的某一位数字;
            res.push_back(temp);//每次存储b进制的一位数,从第0位开始存储;
            while(number.size()&&number.back()==0) number.pop_back();//去除前导0;
        }
        cout<<a<<' '<<a_s<<endl;
        cout<<b<<' ';
        for(int i=res.size()-1;i>=0;--i){//输出要从高位输出,而且输出的是字符串;
            if(res[i]>=0&&res[i]<=9) cout<<char(res[i]+'0');
            else if(res[i]>=10&&res[i]<=35) cout<<char(res[i]-10+'A');
            else cout<<char(res[i]-36+'a');
        }
        cout<<endl<<endl;
    }
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值