文章目录

  • 前言:对整数进制转换的理解
    • 1.1进制理解
    • 1.2如何转换?
  • 问题 A: 5201 二进制位
    • 题目描述
    • 参考代码
  • 问题 B: 5202 二进制转化为十六进制
    • 题目描述
    • 参考代码
  • 问题 C: 5203 周易II
    • 题目描述
    • 参考代码
  • 问题 D: 5204 二进制数
    • 题目描述
    • 参考代码
  • 问题 E: 5205 留下最少
    • 题目描述
    • 参考代码
  • 问题 F: 5206 进制转换
    • 题目描述
    • 参考代码

前言:对整数进制转换的理解

1.1进制理解

数制:也称为计数制,是一种计数的方法,是用一组固定的符号和统一的规则来表示数值的方法。在计数过程中采用进位的方法称为进位计数制(进制),包括数位、基数和位权三个要素。

数位:指数字符号在一个数中所处的位置。
基数:指在某种进位计数制中数位上所能使用的数字符号的个数。例如十进制的基数为10。
位权:数制中某一位上的1所表示数值的大小(所处位置的价值)。例如十进制的231,2的位权是100,3的位权是10,1的位权是1。

以2进制下的10011111为例:

首先10011111为二进制数,它的基数是2。那么计算位权的时候位权的底数是2。

数字 1 0 0 1 1 1 1 1
数位 8 7 6 5 4 3 2 1
位权 2 7 2^{7} 27 2 6 2^{6} 26 2 5 2^{5} 25 2 4 2^{4} 24 2 3 2^{3} 23 2 2 2^{2} 22 2 1 2^{1} 21 2 0 2^{0} 20

1.2如何转换?

1.2.1通法:

将b进制下的数转换为十进制下的数,再转换为目标进制下的数。

例如:
10011111十进制表示是: 1 ∗ 2 7 + 0 ∗ 2 6 + 0 ∗ 2 5 + 1 ∗ 2 4 + 1 ∗ 2 3 + 1 ∗ 2 2 + 1 ∗ 2 1 + 1 ∗ 2 0 = 159 1*2^{7}+0*2^{6}+0*2^{5}+1*2^{4}+1*2^{3}+1*2^{2}+1*2^{1}+1*2^{0}=159 1∗27+0∗26+0∗25+1∗24+1∗23+1∗22+1∗21+1∗20=159
再将其转换为7进制下的数:

步骤 被除数 余数
1 159 22 5
2 22 3 1
3 3 0 3

注意商和被除数的更迭。

将余数反序记录为:315
即为所求7进制下的表示。
1.2.1特别转换
二进制、八进制、十六进制由于 2 3 = 8 2^{3}=8 23=8和 2 4 = 16 2^{4}=16 24=16的特殊关系,可以将二进制下的数从末位按三位一组(八进制)或四位一组(十六进制)直接进行转换对应的数字符。对应关系可参考下表:

二进制 八进制 十六进制 十进制
0 0 0 0
1 1 1 1
10 2 2 2
11 3 3 3
100 4 4 4
101 5 5 5
110 6 6 6
111 7 7 7
1000 / 8 8
1001 / 9 9
1010 / A 10
1011 / B 11
1100 / C 12
1101 / D 13
1110 / E 14
1111 / F 15


问题 A: 5201 二进制位

题目描述

给定你一个十进制数n(0 < n < 1000),要求输出其二进制数。

输入

输入有多行,每行包括一个十进制的正整数n。

输出

输出对应的二进制数。

样例输入

1
2
3

样例输出

1
10
11

解析
思路梳理

读入数据后记录每次对2取的余数,并反序输出。

细节提示

reverse()函数可以用于

  1. 翻转数组:reverse(a,a+n);
  2. 翻转字符串:reverse(str.begin(),str.end());
  3. 翻转向量:reverse(vec.begin(), vec.end());

参考代码

#include<bits/stdc++.h>
using namespace std;
int main(){int n;while(cin>>n){string s0;while(n>1){s0 += to_string(n % 2);n /= 2;}reverse(s0.begin(), s0.end());cout << n << s0 << endl;}return 0;
}


问题 B: 5202 二进制转化为十六进制

题目描述

输入一个2进制的数,要求输出该2进制数的16进制表示。在16进制的表示中,A-F表示10-15。

输入

第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个以0和1组成的字符串,字符串长度至少是1,至多是10000。

输出

n行,每行输出对应一个输入。

样例输入

2
100000
111

样例输出

20
7

解析
思路梳理

2进制转16进制可以以四位为一组进行转换。

细节提示

考虑到二进制数的长度至多有1000位,我们需要以字符串形式输入。且以四位为一组时应该从最右位开始分组。

参考代码

#include<bits/stdc++.h>
using namespace std;
int main(){int n;cin >> n;while(n--){string num, s0, res;cin >> num;while(num.length()>=4){s0 = num.substr(num.length() - 4, 4);num = num.substr(0, num.length() - 4);int nx = (s0[0] - '0') * 8 + (s0[1] - '0') * 4 + (s0[2] - '0') * 2 + (s0[3] - '0');if(nx<10)res += to_string(nx);elseres.push_back(char(nx - 10 + 'A'));}reverse(res.begin(), res.end());if(num.length()==0)cout << res;else if (num.length() == 1)cout << num << res;else if(num.length() == 2)cout << (num[0] - '0') * 2 + (num[1] - '0') << res;else if(num.length()==3)cout << (num[0] - '0') * 4 + (num[1] - '0')*2+(num[2]-'0') << res;cout << endl;}return 0;
}


问题 C: 5203 周易II

题目描述

有人说,中国古代的“周易”是二进制系统的起源,在该系统中,他们用“- -”表示1,“—”表示0。因此,二进制数字“011010”可以表述为“—\n- -\n- -\n—\n- -\n—\n”(符号“\n”表示换行)。现在的问题是如何把一个“周易”中的二进制转换为相应的十进制数?

输入

文件中包含多组测试数据。每个测试数据都是以一个数字k (0 < k <= 20)开始,表示这个数在二进制中的位数。接下来就是k行,就是字符串—或- -,第1位表示最高位。

输出

对于每组测试数据,输出对应的十进制数。

样例输入

3
- -
- -
- -
3
---
---
---
6
---
- -
- -
---
- -
---

样例输出

7
0
26

解析
思路梳理

这题比较简单,思路和问题A差不多,比问题A还简单一些。

细节提示

实际进行数据测试时,如果直接使用st.compare("---")==0来判断字符会无法通过,可能是测试点中并不是每行都是---或者- -,但是前三个字符一定是符合的,所以建议使用st[0]=='-'&&st[1]=='-'&&st[2]=='-'判断。

参考代码

#include<bits/stdc++.h>
using namespace std;
const int N = 30;
int nx[N];
int main(){int n;while(scanf("%d ",&n)!=EOF){//多扫描一个空格避免换行存在int i = 0;while(n--){string st;getline(cin, st);if (st[0]=='-'&&st[1]=='-'&&st[2]=='-')nx[i++] = 0;else if(st[0]=='-'&&st[1]==' '&&st[2]=='-')nx[i++] = 1;}if(i>=1){long long ind = 1, res = 0;for (i-=1; i >= 0;i--){res += ind * nx[i];ind *= 2;}cout << res << endl;}else if(i==0)cout << 0 << endl;}return 0;
}


问题 D: 5204 二进制数

题目描述

给定一个正整数n,要求输出对应的二进制数中所有数码“1”的位置。注意最低位为第0位。例如13的二进制形式为1101,因此数码1的位置为:0,2,3。

输入

输入文件中的第1行为一个正整数d,表示输入文件中测试数据的个数,1<=d<=10,接下来有d个测试数据。每个测试数据占一行,只有一个整数n,1<=n<= 106。

输出

输出包括d行,即对输入文件中的每个测试数据,输出一行。第i行,1 <= i <= d,以升序的顺序输出第i个测试数据中的整数的二进制形式中所有数码1的位置,位置之间有1个空格,最后一个位置后面没有空格。

样例输入

2
13
127

样例输出

0 2 3
0 1 2 3 4 5 6

解析
思路梳理
先用n%2判断二进制位上是否是1,若是则输出此时的i值,i表示数位,每次进行n/=2后均增加1。
细节提示
注意最后一个数没有空格。

参考代码

#include<bits/stdc++.h>
using namespace std;
int main(){int d;cin >> d;while(d--){int n;cin >> n;int i = 0;while(n>0){int flag = 0;if(n%2==1){cout << i;flag = 1;}n /= 2;i++;if(n!=0&&flag)cout << " ";}cout << endl;}return 0;
}


问题 E: 5205 留下最少

题目描述

给定一个基数b,和b进制下的两个非负整数p和m,计算p%m,并输出b进制下的结果。p%m的结果被定义为非负整数k,要求k是满足p=a * m + k中的最小值(a为某些整数)。

输入

输入包含多组测试数据。每个测试数据占一行,由3个无符号的整数构成,第一个整数为b,一个介于2到10之间的十进制数。第二个为p,可能由1000位的0到b-1构成。第三位是m,由9位0到b-1构成。
最后一个测试数据为0,表示输入结束。

输出

对应每组测试数据,要求输出一行b进制下的p%m。

样例输入

2 1100 101
10 123456789123456789123456789 1000
0

样例输出

10
789

解析
思路梳理
由描述易知,m的值较小,可以用整型储存,所以可以直接定义一个长整型mx来作为m的数值。
利用定理: ( a + b ) m o d c = ( a m o d c + b m o d c ) m o d c (a+b)modc=(amodc+bmodc)modc (a+b)modc=(amodc+bmodc)modc
假如数p表示为561417,进制为8。则p的十进制表示为
5 ∗ 8 5 + 6 ∗ 8 4 + 1 ∗ 8 3 + 4 ∗ 8 2 + 1 ∗ 8 1 + 7 ∗ 8 0 = 189199 5*8^{5}+6*8^{4}+1*8^{3}+4*8^{2}+1*8^{1}+7*8^{0}=189199 5∗85+6∗84+1∗83+4∗82+1∗81+7∗80=189199
假设是对5取余数,此时有

  • (561417)8= ( 5 ∗ 8 5 + 6 ∗ 8 4 + 1 ∗ 8 3 + 4 ∗ 8 2 + 1 ∗ 8 1 + 7 ∗ 8 0 ) m o d 5 (5*8^{5}+6*8^{4}+1*8^{3}+4*8^{2}+1*8^{1}+7*8^{0})mod5 (5∗85+6∗84+1∗83+4∗82+1∗81+7∗80)mod5
  • = ( 8 ∗ ( 5 ∗ 8 4 + 6 ∗ 8 3 + 1 ∗ 8 2 + 4 ∗ 8 1 + 1 ∗ 8 0 ) + 7 ∗ 8 0 ) m o d 5 (8*(5*8^{4}+6*8^{3}+1*8^{2}+4*8^{1}+1*8^{0})+7*8^{0})mod5 (8∗(5∗84+6∗83+1∗82+4∗81+1∗80)+7∗80)mod5
  • = ( 8 ∗ ( 5 ∗ 8 4 + 6 ∗ 8 3 + 1 ∗ 8 2 + 4 ∗ 8 1 + 1 ∗ 8 0 ) m o d 5 + ( 7 ∗ 8 0 ) m o d 5 ) m o d 5 (8*(5*8^{4}+6*8^{3}+1*8^{2}+4*8^{1}+1*8^{0})mod5+(7*8^{0})mod5)mod5 (8∗(5∗84+6∗83+1∗82+4∗81+1∗80)mod5+(7∗80)mod5)mod5
  • = ( ( 5 ∗ 8 4 + 6 ∗ 8 3 + 1 ∗ 8 2 + 4 ∗ 8 1 + 1 ∗ 8 0 ) m o d 5 + ( 7 ∗ 8 0 ) m o d 5 ) m o d 5 ((5*8^{4}+6*8^{3}+1*8^{2}+4*8^{1}+1*8^{0})mod5+(7*8^{0})mod5)mod5 ((5∗84+6∗83+1∗82+4∗81+1∗80)mod5+(7∗80)mod5)mod5
  • =((56141)8 mod 5+(7)8 mod 5 )mod5
  • =…
  • =((5)8 mod 5 +(6)8 mod 5 +(1)8 mod 5 +(4)8 mod 5 +(1)8 mod 5 +(7)8 mod 5)mod 5

也就是说,一个任意进制的数对x取余的结果等于其各个数位上的数对x取余的结果的和再对x取余。
利用这一点,我们可以依次对数p的各个位置上的数进行取余并与上一次取余运算结果相加再取余。也就是代码段

long long px = 0;
for (int i = 0; i < p.length();i++){px = px * b + p[i] - '0';px %= mx;}

的处理方式。
细节提示
注意输出时假如结果的px为0时的输出。

参考代码

#include<bits/stdc++.h>
using namespace std;
int main(){int b;string p, m;while(cin>>b){if (b == 0)break;else{cin >> p >> m;long long mx = 0;for (int i = 0; i < m.length();i++)mx = mx * b + m[i] - '0';long long px = 0;for (int i = 0; i < p.length();i++){px = px * b + p[i] - '0';px %= mx;}if(px==0)cout << 0 << endl;else{string ans;while(px>0){ans += to_string(px % b);px /= b;}reverse(ans.begin(), ans.end());cout << ans << endl;}}}return 0;
}


问题 F: 5206 进制转换

题目描述

编写程序,实现将一个数从一种进制转换到另一种进制。在这些进制中,可以出现的数码有62个:{0-9,A-Z,a-z}。

输入

输入文件的第1行是一个正整数N,表示测试数据的个数,接下来有N行,每行的格式为:输入数据的进制(用十进制表示),输出数据的进制(用十进制表示),最后一个是用输入数据的进制所表示的数。输入/输出数据的进制范围是262,也就是说AZ相当于十进制中的1035,az相当于十进制中的36~61。

输出

对每个测试数据,程序输出3行,第1行是输入数据的进制,空格,然后是在该进制下的输入数据;第2行是输出数据的进制,空格,然后是在该进制下的输出数据;第3行为空行。

样例输入

8
62 2 abcdefghiz
10 16 1234567890123456789012345678901234567890
16 35 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
35 23 333YMHOUE8JPLT7OX6K9FYCQ8A
23 49 946B9AA02MI37E3D3MMJ4G7BL2F05
49 61 1VbDkSIMJL3JjRgAdlUfcaWj
61 5 dl9MDSWqwHjDnToKcsWE1S
5 10 42104444441001414401221302402201233340311104212022133030

样例输出

62 abcdefghiz
2 1101110000010001011111001001011001111100100110001101001000110 1234567890123456789012345678901234567890
16 3A0C92075C0DBF3B8ACBC5F96CE3F0AD216 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
35 333YMHOUE8JPLT7OX6K9FYCQ8A35 333YMHOUE8JPLT7OX6K9FYCQ8A
23 946B9AA02MI37E3D3MMJ4G7BL2F0523 946B9AA02MI37E3D3MMJ4G7BL2F05
49 1VbDkSIMJL3JjRgAdlUfcaWj49 1VbDkSIMJL3JjRgAdlUfcaWj
61 dl9MDSWqwHjDnToKcsWE1S61 dl9MDSWqwHjDnToKcsWE1S
5 421044444410014144012213024022012333403111042120221330305 42104444441001414401221302402201233340311104212022133030
10 1234567890123456789012345678901234567890

解析
思路梳理
此题数据都比较大,建议按字符串输入后直接用数组储存各个位置上的数值大小。

核心代码
核心代码是通过模仿整除法的步骤来进行更迭循获得结果的。

        int k, val = 1;//定义一个val并赋值为1,赋值为1以保证进入while循环//val用于记录记录数据的数组nx中数位数值的和string ans;//ans用于记录每次除法的余数while (val != 0){val = 0;int nut = 0;//nut用于取从高位起的用来做除法的数。k = 0;nut = 0;for (i = 0; i < len;){nut = nut * in + nx[i++];//nut需要加上从上一次除法结束时的商再做除法。nx[k++] = nut / ot;//nx进行数据重置,新填入的数是整个原数做除法之后的商。val += nx[k - 1];nut %= ot;}len = k;/*将余数储存起来*/if (nut < 10)ans.push_back(char(nut + '0'));else if (nut >= 10 && nut <= 35)ans.push_back(char(nut - 10 + 'A'));else if (nut >= 36 && nut <= 61)ans.push_back(char(nut - 36 + 'a'));}

细节提示
注意0~9转为字符时要加上’0’。

参考代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1000;
int nx[N], cx[N];
int main(){int t;cin >> t;int in, ot;string num;while(t--){cin >> in >> ot >> num;cout << in << " " << num << endl;cout << ot << " ";int i = 0, len = num.length();for (; i < len; i++){if(num[i]-'0'<10)nx[i] = num[i] - '0';else if(num[i]>='A'&&num[i]<='Z')nx[i] = num[i] - 'A' + 10;else if(num[i]>='a'&&num[i]<='z')nx[i] = num[i] - 'a' + 36;}int k, val = 1;string ans;while (val != 0){val = 0;int nut = 0;k = 0;nut = 0;for (i = 0; i < len;){nut = nut * in + nx[i++];nx[k++] = nut / ot;val += nx[k - 1];nut %= ot;}len = k;if (nut < 10)ans.push_back(char(nut + '0'));else if (nut >= 10 && nut <= 35)ans.push_back(char(nut - 10 + 'A'));else if (nut >= 36 && nut <= 61)ans.push_back(char(nut - 36 + 'a'));}reverse(ans.begin(), ans.end());cout << ans << endl<< endl;}return 0;
}

NENU进制转换课后练习题解(问题A~问题F)相关推荐

  1. 牛客题霸 [进制转换] C++题解/答案

    进制转换 题目描述 给定一个十进制数M,以及需要转换的进制数N.将十进制数M转化为N进制数 题解: 看似简单的进制转换套路非常多 1.M是32位整数,有可能是负数,所以还要特判一下 2.N的范围是[2 ...

  2. 不怂Java进制转换(洛谷P1143题题解,Java语言描述)

    感慨 Java也能这么好使啊,不容易-- --进阶的JFarmer 题目要求 P1143题目链接 分析 进制转换其实也还好,但既然用了Java,那就得扬眉吐气一次,体会体会利用API轻松秒题的感受,机 ...

  3. 《算法零基础100讲》(第20讲) 进制转换(二) - 进阶[C语言题解]

    文章目录 一. 知识普及 1.1 atoi 1.2 log 1.3 pow 1.4 floor 二. 进阶题解 168. Excel表列名称 171. Excel 表列序号 483. 最小好进制 一. ...

  4. 【题解】【AcWing】3374. 进制转换2

    3374. 进制转换2 原题传送:AcWing 3374. 进制转换2 将 MMM 进制的数 XXX 转换为 NNN 进制的数输出. 输入格式 第一行包括两个整数: MMM 和 NNN . 第二行包含 ...

  5. 洛谷P1017题解 [NOIP2000 提高组] 进制转换

    原文地址:https://luvletter.blog.luogu.org/p1017-ti-jie P1017 [NOIP2000 提高组] 进制转换 题目描述 我们可以用这样的方式来表示一个十进制 ...

  6. SPOJ - BALNUM Balanced Numbers(数位dp+进制转换)

    题目链接:点击查看 题目大意:给出平衡数的定义:每一个偶数出现的次数必须是奇数次,每一个奇数出现的次数必须是偶数次,求给定区间中有多少个平衡数 题目分析:数位dp,这个题目就难在怎么确定状态转移,本来 ...

  7. 【解析】1057 数零壹 (20分)(进制转换)

    立志用更少的代码做更高效的表达 Pat乙级最优化代码+题解+分析汇总-->传送门 给定一串长度不超过 10^5的字符串,本题要求你将其中所有英文字母的序号(字母 a-z 对应序号 1-26,不分 ...

  8. 计算机教育的进制转换,计算机数制及编码进制转换公开课教学教育资料.doc

    计算机数制及编码进制转换公开课教学教育资料.doc 数制与编码进制转换[学情分析]本课内容是在学生已经学习了计算机发展与应用.计算机系统的组成等知识的基础上进行,已经初步知道了人与计算机进行信息交换通 ...

  9. 信息学奥赛一本通 1820:【00NOIP提高组】进制转换 | 洛谷 P1017 [NOIP2000 提高组] 进制转换

    [题目链接] ybt 1820:[00NOIP提高组]进制转换 洛谷 P1017 [NOIP2000 提高组] 进制转换 注意:两OJ上题目内容相同,输入输出要求不同 [题目考点] 1.数制 [解题思 ...

最新文章

  1. 领英Linkedin信息搜集工具InSpy
  2. 身患安全杂症,企业如何“下药”?
  3. c++学习笔记之类的应用
  4. 个人密码安全策略 [转载]
  5. 多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP
  6. JS splice()方法
  7. 用汇编的眼光看C++(之类继承)
  8. 德鲁伊 oltp oltp_深入研究内存中OLTP表的非聚集索引
  9. Miller Rabin算法:大质数判断
  10. quartus仿真10:74283的基本功能
  11. python代码设置环境变量
  12. 从零开始制作PPT(母版设计,素材填充,配色等)
  13. Unity - Timeline 之 Activation track properties(激活轨道的属性)
  14. 请完成设计配置计算机,平面设计师的电脑配置有什么要求?
  15. Protel DXP使用教程 -建立工程与绘制原理图PCB图
  16. APP的文件数据直传腾讯云COS实践
  17. 易客多快排系统部署教程
  18. Python Pygame制作简单五子棋游戏(详细代码+解释)
  19. ZDM2004工具式绘图软件v1.7 for AutoCAD2004 1CD(水电版)
  20. PlSQL和OracleClient

热门文章

  1. 第二十三章《斗地主游戏》第2节:系统功能实现
  2. geany设置运行linux,[操作系统]linux强大IDE——Geany配置说明
  3. zscore函数的数据标准化处理及MATLAB实现
  4. 中国向东盟产业链转移背后的故事
  5. windows10实现nfs文件共享
  6. android apk安装之后不显示不出来,APK安装后在桌面的图标列表里不显示/显示的方法...
  7. 信息安全 python_一种基于Python的信息安全情报收集工具
  8. 数据分析和数据挖掘有啥关系?
  9. linux存储安装教程,在Linux下安装Pngquant的三种方法:从存储库,源代码及使用Cargo安装...
  10. 使用TASSEL学习GWAS笔记(4/6):一般线性模型进行GWAS分析(GLM模型)