c++蓝桥杯之16进制->8进制

在这里插入图片描述

#include<bits/stdc++.h>
#define PI atan(1.0)*4
using namespace std;
char a[1005];
//double r,area;
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        scanf("%s",a);
        //printf("%s",a);
        int l=strlen(a),sum=0;
        int p=1;
        for(int i=l-1;i>=0;i--)//16->10
        {
            if(a[i]>='0'&&a[i]<='9'){
                sum+=(a[i]-'0')*p;
                p*=16;
            }
            else{
                sum+=((a[i]-'A')+10)*p;
                p*=16;
            }
        }
        l=0;
        while(sum){
            a[l++]=(sum%8+'0');
            sum/=8;
        }
        for(int i=l-1;i>=0;i--)
            cout<<a[i];
        cout<<endl;
        //cout<<sum;
    }
	return 0;
}

后来发现没有办法过测试点,于是下载了数据,发现数据如此变态!!!
在这里插入图片描述
于是搜集各种资料,最后借鉴了 远征i 大神的,在此附上链接:[https://www.cnblogs.com/expedition/p/12003115.html],看了之后受益匪浅,佩服。

#include<bits/stdc++.h>
#define PI atan(1.0)*4
using namespace std;
char a[16][5]={"0000","0001","0010","0011","0100","0101","0110","0111",
                 "1000","1001","1010","1011","1100","1101","1110","1111"};
//double r,area;
int main()
{
    int n;
    char x[100000];
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",x);
        string bi;
        int len1=strlen(x);
        for(int i=0;i<len1;i++)//16进制转换为2进制
        {
            int num;
            if(x[i]>='A'&&x[i]<='F')
            {
                num=x[i]-'A'+10;//cout<<num<<endl;
            }
            else{
                num=x[i]-'0';
            }
            bi.append(a[num]);
        }
        int mov;
        int len2=bi.size();
        if(bi[0]=='0')//判断向前移几位
        {
            for(int i=1;i<len2;i++)
            {
                if(bi[i]!='0')//二进制字符串首部有几位连续的'0'
                {
                    mov=i;
                    break;
                }
            }
            for(int i=0;i<len2-mov;i++)
            {
               bi[i]=bi[i+mov];
            }
            bi.erase(len2-mov,mov);
        }
        len2=bi.size();
        int jw=0;
        int sum=0;
        int cc=1;
        string oc;
        string k;
        //从二进制变为八进制,是将二进制字符串从后往前
        //每3位一组【不满3位的,前面补字符'0'】,转换成对应的十进制字符,拼接构造
        //为了简化补字符'0'的操作,直接将二进制字符串从后往前,每3位一组,每组按照百位、十位、个位求和
        //不够3位的,由于补的是'0',所以直接无视这个操作,求和就行
        for(int i=len2-1;i>=0;i--)//2进制转换为8进制
        {
            sum+=(bi[i]-'0')*cc;
            cc*=10;
            jw++;
            if(jw==3||i==0)// j == 3 是满足了 “三个一组” 
            {              // i == 0是满足了“到达二进制串的末尾,无视不够3位一组的情况下补'0'操作”
                if(sum==1)k='1';
                if(sum==10)k='2';
                if(sum==11)k='3';
                if(sum==100)k='4';
                if(sum==101)k='5';
                if(sum==110)k='6';
                if(sum==111)k='7';
                if(sum==0)k='0';
                oc+=k;
                cc=1;
                jw=0;
                sum=0;
            }
        }
        //cout<<oc;
        int len3=oc.size();
        for(int i=len3-1;i>=0;i--)
            printf("%c",oc[i]);
        cout<<endl;
    }
	return 0;
}

在不断地寻找bug中终于过了这道题目。
另外,附上一个简短一些的。

#include<iostream>
#include<string>
using namespace std;
int main(){
    int n=0;
    cin>>n;
    string shiliu,er,ba;
    for(int j=0;j<n;j++){
        er="";
        ba="";
        cin>>shiliu;
        for(int i=0;i<shiliu.size();i++){
    
            switch(shiliu[i]){
                case '0' : er+="0000";break;
                case '1' : er+="0001";break;
                case '2' : er+="0010";break;
                case '3' : er+="0011";break;
                case '4' : er+="0100";break;
                case '5' : er+="0101";break;
                case '6' : er+="0110";break;
                case '7' : er+="0111";break;
                case '8' : er+="1000";break;
                case '9' : er+="1001";break;
                case 'A' : er+="1010";break;
                case 'B' : er+="1011";break;
                case 'C' : er+="1100";break;
                case 'D' : er+="1101";break;
                case 'E' : er+="1110";break;
                case 'F' : er+="1111";break;
                default:break;
            }
        } 
        int length=er.size();
        if(length%3==1) {
            er="00"+er;length+=2;
        }
        else if(length%3==2) {
            er="0"+er;length++;
        }
        for(int k=0;k<length;k+=3){
            int d=4*(er[k]-'0')+2*(er[k+1]-'0')+(er[k+2]-'0');
            ba+=(d+'0');
               }
                int p=0;
        while(ba[p]=='0')p++;
        for(p;p<ba.size();p++)
            cout<<ba[p];
        cout<<endl;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅破苍穹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值