问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由09、大写字母AF组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。
题目分析:
最开始忽略了数量级使用暴力,一下就炸了,仔细看题目发现十六进制数长度有100000,这样用传统的方法肯定不行,我们按照进制转换的思想,先把十六进制数每一位转化成4位二进制数,在把二进制数每三位转化为八进制数。
如十六进制的39 转化为二进制 0011 1001
二进制转化为八进制 00 111 001
这里特别注意,二进制转八进制时应该从后往前,不然会错位,最后对不足三位的做特殊处理。
代码:
#include<iostream>
#include<cstdio>
#include<string.h>
#include<cstring>
using namespace std;
char str[100005],d[16][5] = {"0000","0001","0010","0011",
"0100","0101","0110","0111",
"1000","1001","1010","1011",
"1100","1101","1110","1111"};
char ba[500005],p[8][4] = {"000","001","010","011",
"100","101","110","111"};
int main()
{
int n,a[500000],i;
scanf("%d",&n);
getchar();
while(n--)
{
gets(str);
int len = strlen(str), sum = 0,flag = 0;
for(i = 0; i < len; ++i)
{
if(str[i] <= '9' && str[i] >= '0')
sum = str[i]-'0';
else
sum = str[i]-'A'+10;
strncpy(ba+flag,d[sum],4);
flag += 4;
}
//puts(ba);
len = flag;
flag = 0;
for(i = len-1; i >= 0; i-=3)
{
if(i < 2)
{
break;
}
for(int j = 0; j < 8; ++j)
{
if(strncmp(ba+i-2,p[j],3) == 0)
{
a[flag++] = j;
}
}
}
if(i >= 0)
{
if(i == 1)
{
if(ba[0] == '0' && ba[1] == '1')
printf("1");
else if(ba[0] == '1' && ba[1] == '0')
printf("2");
else if(ba[0] == '1' && ba[1] == '1')
printf("3");
}
else
{
if(ba[0] == '1')
{
printf("1");
}
}
}
for(int i = flag-1; i >= 0; --i)
{
printf("%d",a[i]);
}
printf("\n");
}
return 0;
}