1 条题解

  • 0
    @ 2025-8-24 22:19:58

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar ZolaWatle
    За тебя, Родина-матъ.

    搬运于2025-08-24 22:19:58,当前版本为作者最后更新于2020-04-14 19:19:29,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    P6353 题解

            \ \ \ \ \ \ \ 本题的题目描述十分简洁:

            \ \ \ \ \ \ \ 给你一个二进制的数字,请将其转换到八进制。

            \ \ \ \ \ \ \ 这便是一道很简单的进制转换题。

            \ \ \ \ \ \ \ 解决这道题目,本蒟蒻使用了两种方法,先来看第一种。


    Fa♂一:

            \ \ \ \ \ \ \ 我们可以用现将题中给出的二进制数,先转换成十进制数,再转换成八进制数。

            \ \ \ \ \ \ \ 对于2-10的转换,我们使用“乘权相加”的方法;

            \ \ \ \ \ \ \ 而对于10-8的转换,我们可以利用一个栈,使用“除权取余倒排”的方法。

            \ \ \ \ \ \ \ 在这里不过多赘述,如果还不知道这些算法的,可以前往P1143 进制转换学习。

            \ \ \ \ \ \ \ 下面给出这种算法的部分代码:

    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 l ,在原二进制数前需要补 k k 个前导零。

    • l l 能被 3 3 整除时,k=0 k=0

    • 在其他情况下,k=3l k=3-l % 3 3

            \ \ \ \ \ \ \ 这个结论很容易就能得出,在这里就不细说了。

            \ \ \ \ \ \ \ 那么我们可以得到以下的代码:

    k=3-l%3;
    if(l%3==0)
    	k=0;
    

            \ \ \ \ \ \ \ 我们可以定义一个 string string 类型的变量 a a ,表示添加前导零后的二进制数,很容易得到,新的位数 l l' 是等于 l l + k k 的。

            \ \ \ \ \ \ \ 这个过程的代码:

    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表示原二进制数 
    

            \ \ \ \ \ \ \ 接下来,我们按照题中所说,把新得到的二进制数三位三位地分组,再判断每一组表示八进制中的哪个数字。

            \ \ \ \ \ \ \ 有些细节东西还是得看注释:

    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 进制转换


    希望疫情早日过去!

    • 1

    信息

    ID
    5392
    时间
    1000ms
    内存
    32MiB
    难度
    2
    标签
    递交数
    0
    已通过
    0
    上传者