NENU进制转换课后练习题解(问题A~问题F)
文章目录
- 前言:对整数进制转换的理解
- 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()函数可以用于
- 翻转数组:
reverse(a,a+n);
- 翻转字符串:
reverse(str.begin(),str.end());
- 翻转向量:
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)相关推荐
- 牛客题霸 [进制转换] C++题解/答案
进制转换 题目描述 给定一个十进制数M,以及需要转换的进制数N.将十进制数M转化为N进制数 题解: 看似简单的进制转换套路非常多 1.M是32位整数,有可能是负数,所以还要特判一下 2.N的范围是[2 ...
- 不怂Java进制转换(洛谷P1143题题解,Java语言描述)
感慨 Java也能这么好使啊,不容易-- --进阶的JFarmer 题目要求 P1143题目链接 分析 进制转换其实也还好,但既然用了Java,那就得扬眉吐气一次,体会体会利用API轻松秒题的感受,机 ...
- 《算法零基础100讲》(第20讲) 进制转换(二) - 进阶[C语言题解]
文章目录 一. 知识普及 1.1 atoi 1.2 log 1.3 pow 1.4 floor 二. 进阶题解 168. Excel表列名称 171. Excel 表列序号 483. 最小好进制 一. ...
- 【题解】【AcWing】3374. 进制转换2
3374. 进制转换2 原题传送:AcWing 3374. 进制转换2 将 MMM 进制的数 XXX 转换为 NNN 进制的数输出. 输入格式 第一行包括两个整数: MMM 和 NNN . 第二行包含 ...
- 洛谷P1017题解 [NOIP2000 提高组] 进制转换
原文地址:https://luvletter.blog.luogu.org/p1017-ti-jie P1017 [NOIP2000 提高组] 进制转换 题目描述 我们可以用这样的方式来表示一个十进制 ...
- SPOJ - BALNUM Balanced Numbers(数位dp+进制转换)
题目链接:点击查看 题目大意:给出平衡数的定义:每一个偶数出现的次数必须是奇数次,每一个奇数出现的次数必须是偶数次,求给定区间中有多少个平衡数 题目分析:数位dp,这个题目就难在怎么确定状态转移,本来 ...
- 【解析】1057 数零壹 (20分)(进制转换)
立志用更少的代码做更高效的表达 Pat乙级最优化代码+题解+分析汇总-->传送门 给定一串长度不超过 10^5的字符串,本题要求你将其中所有英文字母的序号(字母 a-z 对应序号 1-26,不分 ...
- 计算机教育的进制转换,计算机数制及编码进制转换公开课教学教育资料.doc
计算机数制及编码进制转换公开课教学教育资料.doc 数制与编码进制转换[学情分析]本课内容是在学生已经学习了计算机发展与应用.计算机系统的组成等知识的基础上进行,已经初步知道了人与计算机进行信息交换通 ...
- 信息学奥赛一本通 1820:【00NOIP提高组】进制转换 | 洛谷 P1017 [NOIP2000 提高组] 进制转换
[题目链接] ybt 1820:[00NOIP提高组]进制转换 洛谷 P1017 [NOIP2000 提高组] 进制转换 注意:两OJ上题目内容相同,输入输出要求不同 [题目考点] 1.数制 [解题思 ...
最新文章
- 领英Linkedin信息搜集工具InSpy
- 身患安全杂症,企业如何“下药”?
- c++学习笔记之类的应用
- 个人密码安全策略 [转载]
- 多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP
- JS splice()方法
- 用汇编的眼光看C++(之类继承)
- 德鲁伊 oltp oltp_深入研究内存中OLTP表的非聚集索引
- Miller Rabin算法:大质数判断
- quartus仿真10:74283的基本功能
- python代码设置环境变量
- 从零开始制作PPT(母版设计,素材填充,配色等)
- Unity - Timeline 之 Activation track properties(激活轨道的属性)
- 请完成设计配置计算机,平面设计师的电脑配置有什么要求?
- Protel DXP使用教程 -建立工程与绘制原理图PCB图
- APP的文件数据直传腾讯云COS实践
- 易客多快排系统部署教程
- Python Pygame制作简单五子棋游戏(详细代码+解释)
- ZDM2004工具式绘图软件v1.7 for AutoCAD2004 1CD(水电版)
- PlSQL和OracleClient
热门文章
- 第二十三章《斗地主游戏》第2节:系统功能实现
- geany设置运行linux,[操作系统]linux强大IDE——Geany配置说明
- zscore函数的数据标准化处理及MATLAB实现
- 中国向东盟产业链转移背后的故事
- windows10实现nfs文件共享
- android apk安装之后不显示不出来,APK安装后在桌面的图标列表里不显示/显示的方法...
- 信息安全 python_一种基于Python的信息安全情报收集工具
- 数据分析和数据挖掘有啥关系?
- linux存储安装教程,在Linux下安装Pngquant的三种方法:从存储库,源代码及使用Cargo安装...
- 使用TASSEL学习GWAS笔记(4/6):一般线性模型进行GWAS分析(GLM模型)