Contest100000579 - 《算法笔记》3.5小节——入门模拟->进制转换

常用模板

其它进制转十进制

P进制数 x = a 1 a 2 a 3 . . . a n x = a_1a_2a_3...a_n x=a1a2a3...an转换为十进制数y:
y = a 1 ∗ P n − 1 + a 2 ∗ P n − 2 + . . . + a n − 1 ∗ P + a n y = a_1*P^{n-1}+a_2*P^{n-2}+...+a_{n-1}*P+a_n y=a1Pn1+a2Pn2+...+an1P+an

int y = 0, product = 1; // product在循环中会不断乘P,得到1、P、P^2、...
while (x != 0)
{
	y = y + (x % 10) * product; // x % 10 是为了每次获取x的个位数
	x = x / 10; // 去掉x的个位
	product *= P;
}

十进制转其它进制

十进制数y转换为Q进制数 z = a 1 a 2 a 3 . . . a n z = a_1a_2a_3...a_n z=a1a2a3...an

int ans[40], num = 0; // 数组ans存放Q进制数z的每一位,num为数位
do
{
	ans[num++] = y % Q; // 除基取余
	y = y / Q;
} while(y != 0); // 当商不为0时进行循环
ans[num] = '\0'; // 别忘加字符串终止符

这样ans数组从高位ans[num - 1]到低位ans[0]即为Q进制z,进制转换完成。不过要注意一点就是循环体用的是do…while语句而不是while。因为如果十进制数恰好等于0,那么使用while语句将使循环直接跳出,导致结果出错。实际上,十进制数y为0时其Q进制数也应为0。


问题 A: 又一版 A+B

题目描述

输入两个不超过整型定义的非负10进制整数A和B(<=231-1),输出A+B的m (1 < m <10)进制数。

输入

输入格式:测试输入包含若干测试用例。每个测试用例占一行,给出m和A,B的值。
当m为0时输入结束。

输出

输出格式:每个测试用例的输出占一行,输出A+B的m进制数。

样例输入

2 4 5
8 123 456
0

样例输出

1001
1103

Note

注意输入的两个数相加后的结果可能会超过int和long的范围。

#include 
using namespace std;

int main()
{
    long long A, B, C, m;
    while (scanf("%lld%lld%lld", &m, &A, &B), m)
    {
        C = A + B;
        int ans[40], num = 0;

        do {
            ans[num++] = C % m;
            C = C / m;
        } while (C);

        for (int i = num - 1; i >= 0; --i)
            printf("%d", ans[i]);
        printf("\n");
    }

 	return 0;
}


问题 B: 数制转换

题目描述

求任意两个不同进制非负整数的转换(2进制~16进制),所给整数在long所能表达的范围之内。
不同进制的表示符号为(0,1,…,9,a,b,…,f)或者(0,1,…,9,A,B,…,F)。

输入

输入只有一行,包含三个整数a,n,b。a表示其后的n 是a进制整数,b表示欲将a进制整数n转换成b进制整数。a,b是十进制整数,2 <= a,b <= 16。

输出

可能有多组测试数据,对于每组数据,输出包含一行,该行有一个整数为转换后的b进制数。输出时字母符号全部用大写表示,即(0,1,…,9,A,B,…,F)。

样例输入

4 123 10

样例输出

27

Note

可能题目信息描述的不是很准确,我也读了很久。题目的意思是将a进制的n转换为b进制然后输出。很多人可能奇怪,既然都是整数了,为什么又扯到符号呢?其实这个“整数”的涵盖范围很大。比如十六进制的A6就是十六进制的整数,但用十进制表示不出来,所以用字母。所以输入的“整数”中是可能含有字母的,转换后的整数也是有可能含有字母的,因此要用字符串存储和表示不同进制的数。我代码中的重点在于对字符转数字以及数字转字符的处理。

#include 
#include 
using namespace std;

int main()
{
    int a, b;
    char n[40];
    while (scanf("%d%s%d", &a, n, &b) != EOF)
    {
        int temp = 0, product = 1, num = 0; // 十进制数temp和乘积
        for (int i = strlen(n) - 1; i >= 0; --i)
        {
            if (n[i] >= '0' && n[i] <= '9')
                temp += (n[i] - '0') * product;
            else if (n[i] >= 'a' && n[i] <= 'f')
                temp += (n[i] - 87) * product;
            else if (n[i] >= 'A' && n[i] <= 'F')
                temp += (n[i] - 55) * product;
            product *= a;
        }

        char ans[40];
        do {
            int y = temp % b;
            ans[num++] = y >= 10 ? y + 55 : y + '0'; // 注意+55和+'0'的区别
            temp /= b;
        } while(temp);
        ans[num] = '\0';

        for (int i = num - 1; i >= 0; --i)
            printf("%c", ans[i]);
        printf("\n");
    }

 	return 0;
}


问题 C: 进制转换

题目描述

将一个长度最多为30位数字的十进制非负整数转换为二进制数输出。

输入

多组数据,每行为一个长度不超过30位的十进制非负整数。
(注意是10进制数字的个数可能有30个,而非30bits的整数)

输出

每行输出对应的二进制数。

样例输入

985
211
1126

样例输出

1111011001
11010011
10001100110

Note

非常好的一个题目,强烈建议一定要完全弄懂。最基本的思路是:用字符串来存储数字,即使是long long也只能存到18位整数;然后我们勇字符串数组模拟除法,实质就是针对每一位的除法。这是很方便的,比如5 / 2,在计算机中得到的结果就是2,也就是商,而它的余数可作为后一位的“补10”处理。注意啦,这里的“补10”要好好理解一下。最后要注意的就是在哪里设置循环,用什么循环(结合本博客最上方的常用模板那句话来理解),循环的条件怎么设置,什么时候字符转数字什么时候又反过来。细节不多说,看代码,不明白的欢迎在评论区留言,我会及时回复并且更新注释的。

#include 
#include 
using namespace std;

int main()
{
    char dec[40];
    while (scanf("%s", &dec) != EOF)
    {
        char bin[500];
        int num = 0, re;
        do
        {
            re = 0;
            for (int i = 0; dec[i] != '\0'; ++i) // 进行每一位的除法,每位的余数向后一位进位
            {
                int temp = re; // 用temp保存前一位的进位
                re = (dec[i] - '0') % 2; // 求出余数,更新进位
                dec[i] = (dec[i] - '0'+ temp * 10) / 2 + '0'; // 做除法,记得+'0'转换为字符
            }
            bin[num++] = re + '0'; // 最后剩下的余数就是二进制位,别忘记re是整数,要转为字符

            if (dec[0] == '0' && strlen(dec) != 1) // 如果做完除法后最高位为0,且此时还不是个位数,则需要字符串前移
            {
                int j = 0;
                for (int i = 1; dec[i] != '\0'; ++i)
                    dec[j++] = dec[i];
                dec[j] = '\0'; // 别忘加字符串终止符
            }

        } while (dec[0] != '0');
        bin[num] = '\0';

        for (int i = num - 1; i >= 0; --i)
            printf("%c", bin[i]);
        printf("\n");
    }
 	return 0;
}


问题 D: 八进制

题目描述

输入一个整数,将其转换成八进制数输出。

输入

输入包括一个整数N(0<=N<=100000)。

输出

可能有多组测试数据,对于每组数据,
输出N的八进制表示数。

样例输入

9
8
5

样例输出

11
10
5

Note

无。

#include 
using namespace std;

int main()
{
    int N;
    while (scanf("%d", &N) != EOF)
    {
        int ans[40], num = 0;
        do {
            ans[num++] = N % 8;
            N = N / 8;
        } while (N);

        for (int i = num - 1; i >= 0; --i)
            printf("%d", ans[i]);
        printf("\n");
    }

 	return 0;
}


一定要自己写一遍哦~~~

你可能感兴趣的:(#,第3章)