题解 P6353 【[COCI2007-2008#3] OKTALNI】
ZolaWatle
·
·
题解
P6353 题解
$ \ \ \ \ \ \ \ $ _给你一个二进制的数字,请将其转换到八进制。_
$ \ \ \ \ \ \ \ $这便是一道很简单的**进制转换**题。
$ \ \ \ \ \ \ \ $解决这道题目,本蒟蒻使用了两种方法,先来看第一种。
------------
### Fa♂一:
$ \ \ \ \ \ \ \ $我们可以用现将题中给出的**二进制**数,先转换成**十进制**数,再转换成**八进制**数。
$ \ \ \ \ \ \ \ $对于**2-10**的转换,我们使用“**乘权相加**”的方法;
$ \ \ \ \ \ \ \ $而对于**10-8**的转换,我们可以利用一个栈,使用“**除权取余倒排**”的方法。
$ \ \ \ \ \ \ \ $在这里不过多赘述,如果还不知道这些算法的,可以前往[P1143 进制转换](https://www.luogu.com.cn/problem/P1143)学习。
$ \ \ \ \ \ \ \ $下面给出这种算法的**部分**代码:
```cpp
std::cin>>a;
l=a.length(); //使用string类型存储初始的二进制数
for(int i=l-1;i>=0;i--) //字符串的最后一个字符代表的是权值最小的数位
{
num=a[i]-48; //将字符转化为数值(num=a[i]-'0')
ten+=num*mpow(2,l-i-1); //mpow指乘方运算,当然,可以使用快速幂
}
while(ten>0) //将十进制转换为八进制
{
b[++t]=ten%8; //取余
ten/=8; //除权
}
for(re i=t;i>=1;i--) //倒排
std::cout<<b[i];
```
------------
### Fa♂二:
$ \ \ \ \ \ \ \ $既然题中已经说明了将二进制转换为八进制的具体操作流程,我们可以按照题中所说的方法进行转换。
$ \ \ \ \ \ \ \ $~~提示不是白给的~~
$ \ \ \ \ \ \ \ $那么按照题中的说法,我们大可以这样做这道题:
$ \ \ \ \ \ \ \ $首先,我们考虑在原二进制数前添加前导零的情况:
- 设原二进制数的位数为 $ l $,在原二进制数前需要补 $ k $ 个前导零。
- 当 $ l $ 能被 $ 3 $ 整除时,$ k=0
$ \ \ \ \ \ \ \ $那么我们可以得到以下的代码:
```cpp
k=3-l%3;
if(l%3==0)
k=0;
```
------------
$ \ \ \ \ \ \ \ $我们可以定义一个 $ string $ 类型的变量 $ a $,表示添加前导零后的二进制数,很容易得到,新的位数 $ l' $ 是等于 $ l $ + $ k $ 的。
$ \ \ \ \ \ \ \ $这个过程的代码:
```cpp
for(long long i=1;i<=k;i++) //开long long只是为了保险
a+="0"; //+=,string类型基本操作
for(long long i=k+1;i<=l+k;i++)
a+=str[i-k-1];
//这里的str表示原二进制数
```
------------
$ \ \ \ \ \ \ \ $接下来,我们按照题中所说,把新得到的二进制数三位三位地分组,再判断每一组表示八进制中的哪个数字。
$ \ \ \ \ \ \ \ $有些细节东西还是得看注释:
```cpp
long long i=0;
while(i<l) //防止越界
{
string tmp=""; //定义临时变量,存每一组数
for(re j=1;j<=3;j++) //三个三个分一组
{
tmp+=a[i];
i++; //当前位置扫描过,++。
}
if(tmp=="000") std::cout<<0;
else if(tmp=="001") std::cout<<1;
else if(tmp=="010") std::cout<<2;
else if(tmp=="011") std::cout<<3;
else if(tmp=="100") std::cout<<4;
else if(tmp=="101") std::cout<<5;
else if(tmp=="110") std::cout<<6;
else if(tmp=="111") std::cout<<7;
//无脑判断即可。
}
```
------------
$ \ \ \ \ \ \ \ $这就是做道题的思路及方法,完整代码就不贴了。
$ \ \ \ \ \ \ \ $双倍经验:[P1143 进制转换](https://www.luogu.com.cn/problem/P1143)
------------
希望疫情早日过去!