一、进制的基础知识
1、什么是进制?
进制也就是进位计数制,是人为定义的带进位的计数方法。对于任何一种进制X进制,就表示每一位置上的数运算时都是逢X进一位。 十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,以此类推,x进制就是逢x进位。
2、生活中常见的进制有哪些?
10进制、60进制、12进制、24进制等;
3、n进制如何数数?
10进制:0 1 2 3 4 5 6 7 8 9 10 11……
2进制:0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111 10000……
8进制:0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21……
16进制:0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20……
二、十进制转换为R进制
1、十进制整数转换成R进制的整数: 除R取余法 。☆☆☆☆☆
2、学习技巧:可以参照短除法,短除法的作用是用来拆出10进制n的每一位,可以理解为10进制转10进制,使用的方法是除10取余,然后倒过来;
那么10进制转R进制,自然就是除R取余,然后倒过来;
三、R进制转换为十进制
1、R进制转10进制整数: 按权展开 。
按权展开:基数为N的数字,只要将各位数字与它的权相乘,其积相加,和数就是十进制数。
2、学习技巧: 可以参照10进制整数计算机制来学习 ;
12345=5 * 1 + 4 * 10 + 3 * 100 + 2 * 1000 + 1 * 10000
=5 * 100 + 4 * 101 + 3 * 102 + 2 * 103 + 1 * 104
四、10进制和R进制互转程序实现
正整数N转换成一个二进制数
题目描述
输入一个不大于32767的整数n,将它转换成一个二进制数。
输入
输入只有一行,包括一个整数n(0<=n<=32767)
输出
输出只有一行。
样例
输入
100
输出
1100100
定义字符串存储N转换的二进制数
用短除法除2取余,将余数逆序存入字符串r。
-
#include<bits/stdc++.h>
-
-
using namespace std;
-
-
-
//10进制转2进制
-
-
int n;
-
-
string r = "";//存放转换结果
-
-
int main(){
-
-
cin>>n;
-
-
//当n!=0循环
-
-
while(n != 0){
-
-
//cout<<n%2;//取余
-
-
//将n%2的结果转换为字符+到r前面
-
-
r = char(n%2+'0') + r;
-
-
n=n/2;//除2
-
-
}
-
-
-
-
//特判输入为0的情况
-
-
if(r == "") cout<<0;
-
-
else cout<<r;
-
-
return 0;
-
-
}
注意:
强制类型转换
int y = 97;
cout<<y<<endl;
//输出ascii码为y的字母
cout<<char(y)<<endl;
在进制转换的题目中,一定要特别注意输入为0的情况。
正整数n转换为16进制
题目描述
请从键盘读入一个非负整数 n( n 是一个不超过 18 位的非负整数),将 n 转换为 16 进制!
注意:16 进制即逢 16 进 1,每一位上可以是从小到大为0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F共 16 个大小不同的数,即逢 16 进 1,其中用 A,B,C,D,E,F 这六个字母来分别表示 10,11,12,13,14,15。
如:60 的十六进制为 3C。(字母请用大写)
输入
一个不超过 181818 位的非负整数 nnn 。
输出
该数的十六进制值。
样例
输入
100000000000
输出
174876E800
思路:除16取余!
逆序存储到字符串时要注意:
整数0~9,转换为字符’0’~’9’,x + ‘0’
整数10~15,转换为字符’A’~’F’,x + ‘A’ - 10
解法一:分别判断n%16结果在0~9及10~15的哪个范围,分别转换为对应的字符
-
#include<bits/stdc++.h>
-
-
using namespace std;
-
-
-
long long n;
-
-
string r = "";//存放16进制
-
-
-
int main(){
-
-
cin>>n;
-
-
//特判输入为0的情况
-
-
if(n == 0){
-
-
cout<<0;
-
-
return 0;//停止函数
-
-
}
-
-
-
-
//短除法
-
-
while(n != 0){
-
-
//n%16:如果在0~9之间,转换为字符'0'~'9'
-
-
//如果在10~15之间,转换为字符'A'~'F'
-
-
if(n%16 <= 9){
-
-
r = char(n%16+'0') + r;
-
-
}else{
-
-
r = char(n%16+55) + r;
-
-
}
-
-
-
-
n = n / 16;//除16
-
-
}
-
-
-
-
cout<<r;
-
-
return 0;
-
-
}
解法二:用字符串存储十六进制对应的字符,简化16进制转为字符的过程
-
#include<bits/stdc++.h>
-
-
using namespace std;
-
-
-
long long n;
-
-
string r = "";//存放16进制
-
-
string t = "0123456789ABCDEF";//存放0~15对应的字符
-
-
-
int main(){
-
-
cin>>n;
-
-
//特判输入为0的情况
-
-
if(n == 0){
-
-
cout<<0;
-
-
return 0;//停止函数
-
-
}
-
-
-
-
//短除法
-
-
while(n != 0){
-
-
//n%16:如果在0~9之间,转换为字符'0'~'9'
-
-
//如果在10~15之间,转换为字符'A'~'F'
-
-
r = t[n%16] + r;
-
-
n = n / 16;//除16
-
-
}
-
-
-
-
cout<<r;
-
-
return 0;
-
-
}
注意:
int最多表达到231-1,10位整数;
long long最多表达到263-1,19位整数;
10进制转D进制
题目描述
十进制整数 N 和其他 D(D的值为 2、8、16)进制数的转换是计算机实现计算的基本问题,其解决方法很多,其中一个简单算法就是除 D 取余,然后倒过来得到 D 进制的数。
例如:
(1348)10=(10101000100)2
(1348)10=(2504)8
(1000)10=(3E8)16
(请注意:转 16 进制时 用 A 代表余数 10 ,B 代表余数 11 ……)
假设现要编制一个满足下列要求的程序:对于输入的任意一个非负十进制整数(n≤1,000,000,000),打印输出与其等值的 D 进制数。
输入
有两个整数 N 和 D,N 表示要转换的十进制非负整数, D 代表要转换的进制(2、8或16)
输出
N 进制转 D 进制的结果。
样例
输入
1348 2
输出
10101000100
-
#include <bits/stdc++.h>
-
-
using namespace std;
-
-
-
string t = "0123456789ABCDEF",r = "";
-
-
int n,d;
-
-
int main(){
-
-
cin>>n>>d;
-
-
while(n != 0){
-
-
r = t[n%d] + r;
-
-
n = n / d;
-
-
}
-
-
-
if(r == "") cout<<0;
-
-
else cout<<r;
-
-
return 0;
-
-
}
二进制转换十进制
题目描述
请将一个25位以内的2进制正整数转换为10进制!
输入
一个25位以内的二进制正整数
输出
该数对应的十进制
样例
输入
111111111111111111111111
输出
16777215
1 |
1 |
0 |
1 |
|||||||||
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
|
()-1 |
思路:从最低位开始(()-1),倒过来计算(按权展开)
s[i] – ‘0’
准备变量t表示2的n次方,t = 1每循环一次,t = t * 2
-
#include<bits/stdc++.h>
-
-
using namespace std;
-
-
-
string s;
-
-
int t = 1;//表示2的次方,默认是2的0次方
-
-
int r = 0;//表示2进制对应的10进制
-
-
-
int main() {
-
-
cin>>s;
-
-
//倒过来按权展开
-
-
for(int i = s.size() - 1;i >= 0;i--){
-
-
//s[i] - '0':获得s[i]这个字符对应的整数
-
-
r = r + (s[i] - '0') * t;
-
-
t = t * 2;
-
-
}
-
-
-
-
cout<<r;
-
-
return 0;
-
-
}
十六进制转十进制
题目描述
请将一个不超过10位的十六进制正整数转换为十进制整数。
输入
10位以内的十六进制正整数,如果该十六进制中有字母,字母用大写英文字母表示。
输出
该数对应的十进制整数。
样例
输入
2ECF
输出
11983
2 |
E |
C |
F |
|||||||||
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
思路:逆序计算,按权展开!
从s中获取每一位s[i]是字符,要转换为实际的整数!
s[i]:’0’~‘9’,s[i] – ‘0’
s[i]:’A’~’F’,s[i] – ‘A’ + 10
-
#include<bits/stdc++.h>
-
-
using namespace std;
-
-
-
string s;
-
-
long long r = 0,t = 1;//t表示权重(16的次方)
-
-
-
int main() {
-
-
cin>>s;
-
-
//逆序循环字符串,从最低位开始计算
-
-
for(int i = s.size() - 1;i >= 0;i--){
-
-
//如果当前位是数字字符 0~9
-
-
if(isdigit(s[i])){
-
-
r = r + (s[i] - '0') * t;
-
-
}else{
-
-
//如果是字母 10~15
-
-
r = r + (s[i] - 55) * t;
-
-
}
-
-
-
-
//权重提升
-
-
t = t * 16;
-
-
}
-
-
-
-
cout<<r;
-
-
return 0;
-
-
}
小丽找半个回文数
题目描述
小丽同学在编程中学到了回文数的概念,如果一个数正过来读和反过来读是同一个数,那么这个数就是回文数;比如:2、5、8、66、121、686、12321都是回文数,小丽发现,这样的数不算多。于是小丽有个想法,如果这个数不是回文数,但这个数在2进制或者16进制下是回文数,就算这个整数是半个回文数,比如417并不是回文,但417对应的16进制数是1A1是回文数,因此417算半个回文数。
请你编程帮助小丽找符合条件的半个回文数。
输入
第一行是一个整数n(10<=n<=100)
第二行是n个整数(这些整数都是0~10^8之间的整数)
输出
所有符合条件的半个回文数,每行一个。
样例
输入
-
5
-
121 417 27 100 21
输出
-
417
-
27
-
21
-
#include<bits/stdc++.h>
-
-
using namespace std;
-
-
-
/*
-
-
半个回文:数字x在10进制下不是回文,
-
-
在2进制或者16进制下是回文
-
-
*/
-
-
//判断整数n在d进制下是否是回文
-
-
bool huiwen(int n,int d){
-
-
string r = "",t = "0123456789ABCDEF";
-
-
while(n != 0){
-
-
r = t[n%d] + r;
-
-
n = n / d;
-
-
}
-
-
-
//判断r是否是回文
-
-
string r2 = r;
-
-
reverse(r2.begin(),r2.end());
-
-
//cout<<r<<" "<<r2;
-
-
if(r == r2){
-
-
return true;
-
-
}else{
-
-
return false;
-
-
}
-
-
}
-
-
-
int main() {
-
-
int n,x;
-
-
cin>>n;
-
-
for(int i = 1;i <= n;i++){
-
-
cin>>x;
-
-
if(huiwen(x,10)==false&&(huiwen(x,2)==true||huiwen(x,16))){
-
-
cout<<x<<endl;
-
-
}
-
-
}
-
-
return 0;
-
-
}