题目链接:十六进制转八进制
思路:把十六进制转换成二进制,再把二进制转换成八进制
- 设置一个字符串
string temp="0123456789ABCDEF"
,方便找到输入字符串中每个字母对应的十进制 - 对于输入的字符串s,遍历每个字母
s[i]
,使用temp.find(s[i])
,找到s[i]
对应的十进制t
。把十进制t
转换成二进制,并存储在数组er中。注意每轮都需要对数组er清零。 - 输入字符串
s
的长度记为len
,则数组er
的长度为4*len
,判断4*len
对3取模,余数记为mod
。如果mod=2,ans[0]=er[1]+er[0]*2
;如果mod=1,ans[0]=er[0]
。接下来从mod
开始,每三位转换为一个八进制,并存储在ans中 - 对ans进行输出,需要对首位单独判断。
#include <bits/stdc++.h>
using namespace std;
string temp="0123456789ABCDEF";
int ans[500000];
int main()
{
// #ifdef ONLINE_JUDGE
// #else
// freopen("input1.txt", "r", stdin);
// #endif
int n;
string s;
cin>>n;
while(n--)
{
cin>>s;
int len=(int)s.length();
int er[500000];//二进制
memset(er,0,sizeof(er));
for(int i=0;i<len;i++)
{
int t=temp.find(s[i]);//找到输入字符串中每个字母对应的十进制,接下来开始把十进制转换成二进制
er[i*4+3]=t%2;t/=2;
er[i*4+2]=t%2;t/=2;
er[i*4+1]=t%2;t/=2;
er[i*4]=t%2;
}
int cnt=0;//记录八进制ans的下标
memset(ans,0,sizeof(ans));
//二开始把进制转八进制
int mod=(4*len)%3;
if(mod==2)
ans[cnt++]=er[1]+er[0]*2;
else if(mod==1)ans[cnt++]=er[0];
for(int i=mod;i<=4*len-3;i+=3)
ans[cnt++]=er[i]*4+er[i+1]*2+er[i+2];
//输出
for(int i=0;i<cnt;i++)
{
if(i==0)//对于首位是0的略过不输出,只有首位不为0才输出
{
if(ans[i]!=0)cout<<ans[i];
}
else
cout<<ans[i];
}
cout<<endl;
}
return 0;
}
最后:
代码调了三天的血泪史:平时习惯于把输入数据存放在txt
文件中,因为懒得每次运行代码都输入测试数据。即以下语句
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif
但是蓝桥系统貌似不支持这样的语句,同样的答案,上述代码没注释,评测结果就是错的,注释掉之后就对了。。。。