资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
思路: 先把16进制转换成二进制然后再把二进制转换成八进制。
一位16进制数需要4位二进制数表示,一位八进制数需要三位二进制表示。
所以这里我们先把16进制数转换成二进制然后每三个一组转换成八进制。
例如样例:
39(十六进制) 对应的2进制为 0011(3) 1001(9) 然后每三个一组输出分组如下(不足三个的补零) 00 111(7) 001(1) 对应的八进制为71(因为不能用前导0,所以0不输出)
在例如 123ABC 对应的二进制为(四位二进制数对应一个十六进制数)
0001 0010 0011 1010 1011 1100 然后每三个一组划分如下:
00(0)100(4) 100(4) 011(3) 101(5) 010(2) 111(7) 100(4) 故八进制数为443527
废话少说直接贴代码了
#include<bits/stdc++.h>
using namespace std;
const int MAXN=100001*4;
int a[MAXN]={0},b[MAXN];
char str[MAXN/4];
int main(){
int t;
scanf("%d",&t);
while(t--){
int f=4;//记录十六进制数转换成二进制数在数组中的位置
int ans=1;
scanf("%s",str);
int l=strlen(str);
for(int i=l-1;i>=0;i--){
if(str[i]>='A'&&str[i]<='F'){
int temp=str[i]-'A'+10;//转换成数字
for(int j=f-4+1;j<=f;j++){//转换成二进制
a[j]=temp%2;
temp/=2;
}
f+=4; //因为一个十六进制数转换为4为二进制数所以f+4
}
else {
int temp=str[i]-'0';
for(int j=f-4+1;j<=f;j++){
a[j]=temp%2;
temp/=2;
}
f+=4;
}
}
int e=1,count=0;
f=f-4;//因为最后没有运算而且f+4了故应该减去这时候f就指向最后一位二进制了
while(e<=f){//转换成八进制
int sum=0,num=0,q=1;
for(;e<=f;e++){
num=num+a[e]*q;
sum++;
q*=2;
if(sum==3) {
e++;
break;
};
}
b[count++]=num;
}
while(b[count-1]==0){//防止有前导零
count--;
}
for(int i=count-1;i>=0;i--){
printf("%d",b[i]);//输出八进制数
}
printf("\n");
}
return 0;
}