资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
解题思路:由于题目给的十六进制数十分大,用long long也装不下。所以决定使用字符数组的方法实现。首先将十六进制数转换成二进制字符串,再将二进制转换成八进制数。我们都知道,4位二进制构成16进制数,3位二进制数构成8进制数。所以思路十分清晰了,代码实现就ok了。代码写得有点烂,应该可以继续简化。
#include<bits/stdc++.h>
using namespace std;
char data[15][100005];
int res[400005];
int flag=1;
int counts=0;
void Change(int num,int mark)//十六进制转二进制
{
int i=0;
while(num>0)
{
res[mark*4+i]=num%2;
num=num/2;
i++;
}
for(int j=i;j<4;j++)//补成4位
res[mark*4+j]=0;
int temp=res[mark*4];//因为顺序是反的,所以交换位置
res[mark*4]=res[mark*4+3];
res[mark*4+3]=temp;
temp=res[mark*4+1];
res[mark*4+1]=res[mark*4+2];
res[mark*4+2]=temp;
}
void Change2()//二进制转八进制 三位二进制转一位八进制
{
int sum=0,i=0;
if(flag==1 && (counts%3)!=0)//判断二进制数的位数是否是3的倍数,否则特殊处理
{
flag=0;
while(i<counts%3)
{
sum=sum*2+res[i];
i++;
}
if(sum!=0) //去除前导0
cout<<sum;
}
while(i<counts)
{
sum=0;
for(int j=0;j<3;j++)
sum=sum*2+res[i+j];
if(flag==0)
cout<<sum;
else if(flag==1 && sum!=0)//去除前导0
cout<<sum;
i+=3;
if(flag==1)
flag=0;
}
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>data[i];
for(int i=0;i<n;i++)
{
int j=0;
flag=1;
while(data[i][j]!='\0')
{
if(data[i][j]>='0' && data[i][j]<='9')
Change(data[i][j]-'0',j);
else
Change(data[i][j]-'A'+10,j);
j++;
}
counts=j*4;
Change2();
cout<<endl;
}
return 0;
}