资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
解题思路
- 选取一个中间进制数,其幂能转化为十六和八,即为二( 其幂能转化为十六和八,这样就可以对每个单独的数拆分为一定数量的中间进制的数)
- 比如十六进制可以拆分为四个二进制
- 比如八进制可以拆分为三个二进制
- 十六进制转二进制,从前向后转,每次转四个二进制数
- 二进制转八进制,从后向前读,每次读三个二进制转化为一个八进制数,不够的话继续往后读(读到的也是0,即补零)
- 特殊:将十六进制转化为四个二进制,不一定能均分三个将其转化为八进制
-
比如
-
极端情况下,十六进制转化为二进制头部为0001。并且选取的三个数据转为八进制,所以最多补2个0。此时头部极端情况为00 0001,即(000 001).此时我们可以看到,即使是极端情况下也就是只有头部一个数数据为0,所以此时我们只需要判断头部是不是0,来判断是否输出头部即可,而不需要再对其进行判断。
-
代码
#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
char a[15][100000];//char类型数组存储输入数据
bool b[400010];//bool型数组用来存储二进制数
char c[200000];//c用来存储转化为八进制的数据
int main(){
int n;//输入n
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
//num值用来存放临时数据,l存放数据长度,t是转化为二进制的长度
int num,l,t;
for(int i=0;i<n;i++){
l=strlen(a[i]);
t=0;
for(int j=0;j<l;j++){
//将字符型的数据用int型的num表示
if(isdigit(a[i][j])) num = a[i][j]-'0';
else num = a[i][j]-'A'+10;
//将num转化为四个二进制数
for(int z=3;z>=0;z--){
b[j*4+z]=num%2;
num/=2;
}
t+=4;//十六进制每转化一个数据就进行+4
}
//tt用来表示转化为八进制的下标
int tt=0;
//将三个二进制数转化为一个八进制数
for(int T=t-1;T>=0;T-=3){
for(int j=0;j<3;j++)
if(b[T-j]) num+=pow(2,j);//num表示转化为八进制的数
c[tt++]=num+'0';
num=0;
}
//将十六进制转化为四个二进制会出现后面三个均为0的
if(c[tt-1]!='0') cout<<c[tt-1];
for(int j=tt-2;j>=0;j--)
cout<<c[j];
cout<<endl;
}
return 0;
}
最后,有不对的地方欢迎大家指正。有疑问的,可以评论或私信作者,本人尽力解答OvO