进制转换+蓝桥2489和1230题

进制的本质

       进制(或基数)是表示数值的方法,它决定了数位的权重和数位的可能值。进制是基于一个固定的数(称为基数或进位基数)来构建的,每个数位上的数字乘以基数的相应幂次,然后将这些乘积相加得到该数的值。

常见进制

十进制:基数为10,是最常用的进制,也是人类日常生活中使用的进制。在十进制中,每个数位的值可以是0到9中的任意一个数字。

二进制:基数为2,是计算机科学中最基本的进制。在二进制中,每个数位的值只能是0或1。

八进制:基数为8,是一种较少使用的进制,但在某些编程语言中用于简化二进制数的表示。

十六进制:基数为16,是一种常用的进制,特别是在计算机编程中。在十六进制中,每个数位的值可以是0到9中的任意一个数字,以及A到F(或小写a到f)中的任意一个字母,分别代表10到15。

进制在计算机中的应用

在计算机科学中,进制转换非常重要,因为计算机内部使用二进制来表示和处理数据。计算机使用二进制是因为它易于通过电子电路实现,且具有较高的可靠性。十六进制和八进制通常用于简化二进制数的表示,因为它们可以更紧凑地表示相同数量的信息。

将任意进制转换为十进制

在任意进制中,每个数位上的数字乘以该位的权重(基数的幂次),然后将这些乘积相加得到该数的值。例如,二进制数 1011 可以表示为 1×2^3+0×2^2+1×2^1+1×2^0。

以通过遍历数位并计算每个数位的贡献来实现转换:对于数位 a[i],其贡献为 a[i] * (base^i).其中 base 是进制的基数,i 是当前数位的索引(从0开始)

将十进制转换为任意进制

确定进制基数:首先确定目标进制的基数,例如二进制的基数是2,八进制的基数是8,十六进制的基数是16。

2.除基取余:将十进制数除以目标进制的基数,记录余数。然后,将商继续除以基数,重复这个过程,直到商为零。

3.余数逆序排列:将记录的余数逆序排列,得到目标进制的表示。

具体公式如下:

设 𝑛 为十进制数,𝑏为目标进制的基数,r_i为每次除法操作的余数,q_{i}​ 为每次除法操作的商。则转换过程可以表示为:

其中,r_{n}​ 是最后一次除法操作的余数,也是目标进制表示的最低位。

最终,目标进制的表示为r_{n}r^{_{n-1}}...r_{2}r_{1}r_{0}​。

例如,将十进制数 10 转换为二进制:

因此,十进制数 10 的二进制表示为 1010。

例题

1.蓝桥2489进制

请问十六进制数 2021ABCD 对应的十进制是多少?

#include <iostream>
#include<string>

using namespace std;

int turn(char x){
    if(x>='0'&&x<='9'){
        return x-'0'; 
    }else if(x>='A'&&x<='F'){
        return x-'A'+10;
    }else{
        return -1;
    }
}


int main()
{
    string str="2021ABCD";
    int count=0;
    for(int i=0;i<8;i++){
        //cout<<str[i];
        char x=str[i];
        int y=turn(x);
        count=count*16+y;
    }    
    cout<<count<<endl;

    return 0;
}

或者直接用c++的十六进制表示法将0x2021ABCD赋值给一个unsigned int 数字

(在大多数现代系统上,unsigned int 通常是32位的,这意味着它可以表示的最大值是 0xFFFFFFFF(十进制的 4294967295)。因此,0x2021ABCD 是一个有效的值,可以被 unsigned int 类型的变量存储。)

#include <iostream>

int main() {
    unsigned int num = 0x2021ABCD; // 将十六进制数赋值给unsigned int变量
    std::cout << "The value of num is: " << num << std::endl;
    return 0;
}

2.蓝桥1230进制转换

题目描述
给定一个N 进制数S,请你将它转换为M 进制。

输入描述
第一行为一个整数T,表示测试数据数量。 (1≤T≤10^5)
每个测试用例包含两行,第一行包含两个整数N,M。

第二行输入一个字符串S,表示N 进制数。

数据范围保证:2≤N,M≤16,若N≥10,则用A∼F 表示字码10∼15。保证S 对应的十进制数的位数不超过10。

输出描述
输出共T,每行表示一组数据的答案。

输入样例
2
2 10 
10101 
11 2
1793A5068

输出样例
21
10101111001010100111010101011

运行限制
最大运行时间:1s
最大运行内存: 128M

方法:先将N进制数转换为10进制数,再将10进制数转换为M进制数

代码:

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <iostream>
#include <limits>
#include <set>
#include <utility>
#include <vector>
#include <string>

using namespace std;

int turn(char x){
    if(x>='0'&&x<='9'){
        return x-'0'; 
    }else if(x>='A'&&x<='F'){
        return x-'A'+10;
    }else if(x>='a'&&x<='f'){
        return x-'a'+10;
    }else{
        return -1;
    }
}

void reverse(string& str) {
    size_t left = 0;
    size_t right = str.length() - 1;
    while (left < right) {
        // 交换左右两端的字符
        swap(str[left], str[right]);
        // 移动指针
        ++left;
        --right;
    }
}

string NturnM(int x,int M){
    string result;
    int remain;
    if(x==0){
        return "0";
    }
    while(x>0){
        remain=x%M;
        result+=to_string(remain);
        x/=M;
    }
    reverse(result);
    return result;
}

int main()
{
    int T;
    cin>>T;
    while(T--){
        int N,M;
        cin>>N>>M;
        string S;
        cin>>S;
        int count=0;
        int s=S.size();
        for(int i=0;i<s;i++){
            //cout<<str[i];
            char x=S[i];
            int y=turn(x);
            count=count*N+y;
        }    
        string str=NturnM(count,M);
        cout<<str<<endl;
    }



    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值