问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意 】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意 】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
思路:开始以为很简单,先转化成十进制然后再转化即可,但错误后发现每个十六进制数长度不超过100000,数据太大一定会爆。
所以不能转化为十进制,一位16进制可以转化为4位二进制数,而3位二进制数即可转化为一位8进制数。
注意:要注意存储8进制位string的清空,以及补位的时候。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define ll long long
using namespace std;
ll a[1000000];
int main()
{
ll t,ans;
scanf("%lld",&t);
string str1,str2;
while(t--)
{
cin>>str1;
ll l=str1.length();
str2="";//清空str2
for(int i=0;i<l;i++)//转换成二进制
{
switch(str1[i])
{
case'0':str2+="0000";break;
case'1':str2+="0001";break;
case'2':str2+="0010";break;
case'3':str2+="0011";break;
case'4':str2+="0100";break;
case'5':str2+="0101";break;
case'6':str2+="0110";break;
case'7':str2+="0111";break;
case'8':str2+="1000";break;
case'9':str2+="1001";break;
case'A':str2+="1010";break;
case'B':str2+="1011";break;
case'C':str2+="1100";break;
case'D':str2+="1101";break;
case'E':str2+="1110";break;
case'F':str2+="1111";break;
default:break;
}
}
//补齐3的倍数使每三个二进制位刚好能转化为一个八进制位的数
if(str2.length()%3==1)
{
str2="00"+str2;
}
else if(str2.length()%3==2)
{
str2="0"+str2;
}
ans=0;
for(int i=0;i<str2.length();i=i+3)
{
a[ans]=(str2[i]-'0')*4+(str2[i+1]-'0')*2+(str2[i+2]-'0')*1;
ans++;
}
for(int i=0;i<ans;i++)
{
if(a[i]==0&&i==0)
continue;
else
cout<<a[i];
}
cout<<endl;
}
return 0;
}