第1课 进制转换

学习目标

1、理解二进制计数原理。
2、掌握不同进制数之间的转换原理和实现方法。
3、学会使用进制转换的原理解决一些实际问题。

知识讲解

实际生活中,人们使用十进制计数。但是,任何信息在计算机中都是采用二进制编码表示的,有时还会用到十六进制。
十进制计数原理采用“0” ~ “9”十个符号,运算规则为“逢十进一”,基数是十。
二进制计数原理采用“0” 和“1”两个符号,运算规则是“逢二进一”,基数是二。
显然,十进制中的数“10”和二进制中的“10”、十六进制中的“10”是不一样的。为了区分,我们分别表示成(10)10、(10)2、(10)16。有时也会在一个数的后面加上英文字母D、B、H来分别表示该数是十进制数、二进制数或者十六进制数,如96D、110B、2B3FH等。

进制转换的基本原理

不同进制数之间转换的基本原理就是依据其“运算规则”和“权”的含义进行乘除运算。
(1) 二进制数转换成十进制数
一个二进制数转换成十进制数的方法是将其表示成“按权展开式”,再按十进制运算规则求和。这种方法可以扩展到任意 n 进制。
(2) 二进制数与十六进制数之间的相互转换
二进制数转换成十六进制数的方法是以小数点为准,往前、往后“四位一段”分别转换成十六进制数再求和,不满四位要补齐。
(3) 十进制数转换成二进制
十进制数转换成二进制要将整数和小数分开转换,最后再求和。整数的转换方法是:不断除以 2 求余数,最后反序输出;小数的转换方法是:不断乘以 2,将每次得到的整数部分依次输出,并且每次都将整数部分恢复为 0。

进制转换的应用举例
例1 进制转换

【问题描述】
将任意一个 n 进制整数 x 转换成十进制。
【输入格式】
第 1 行 1 个正整数 n,1<n<10;
第 2 行 1 个整数 x。
【输出格式】
一行一个数,表示转换得到的十进制数,保证答案不超过 2147483647。
【输入样例】
2
100110
【输出样例】
38
【问题分析】
读入 n 和 x,根据 n 和 x 的位数,分别求出 x 的每一位对应的“权值”,然后穷举每一位,将它乘以该位对应的权值,累加便可得到结果。
更高效、更简洁的算法是采用“秦九韶公式”。对于样例输入,可以这样计算:
(((((1*2)+0)*2+0)*2+1)*2+1)*2+0=38。具体实现采用“迭代法”,用一个变量不断乘以n,再加上下一位x[i]。

#include<bits/stdc++.h>
using namespace std;
int main(){
    freopen(” change.in ” , ” r ” ,stdin);
    freopen( ” change.out ” , ” w ” ,stdout);
    int n,ans = 0,i = 0;
    char s[32];
    scanf(%d\n ” ,&n);
    while((s[i] = getchar()) != '\n'){  
          ans = ans * n + (s[i] - 48);  
          i++;
    } 
    printf(%d\n ” ,ans);
    return 0;
}

如果10<n<17,,则对于输入的“A” ~ “F"先处理成10 ~ 15 即可。如果要转换的是n进制的实数,可以把整数和小数部分截取出来分别进行转换,最后再合并再一起输出。

例2 汽车牌照

【问题描述】
小 Y 最近发现街上的汽车越来越多了,作为汽车的重要标志——汽车牌照也是越来越不够用了,已经从以前的十进制发展到三十六进制了,以前的一个汽车牌照“苏 D88888”,现在的牌照“苏 D0YY11”。
小 Y 突发其想,想知道他看到的大量汽车牌照中最近的两个汽车牌照相差多少?
【输入格式】
若干行(不超过 500000 行),每行为一个汽车牌照。
每个汽车牌照为一个 7 位的字符串,格式为 SD×××××,其中一个 × 表示一个 0~9 或A~Z,所涉及的字母均为大写。
【输出格式】
一行一个数,表示最接近的两个汽车牌照之间的差值,要求为十进制数。
【输入样例】
SD12345
SD88888
SD22222
SD99999
【输出样例】
1678245
【问题分析】
可以将所有汽车牌照(三十六进制数)转换成使十进制数,然后进行排序,再依次计算相邻两个数的差值,打擂台保留最小值。

例3 数列(蓝桥杯)

【问题描述】
给定一个正整数 k,把所有 k 的方幂及所有有限个互不相等的 k 的方幂之和构成一个递增的序列。例如,当 k=3 时,这个序列是:1,3,4,9,10,12,13,…
请求出这个序列的第 n 项的值(用十进制数表示)。
【输入格式】
一行两个正整数 k 和 n,之间用一个空格隔开,且 3≤k≤15,10≤n≤1000。
【输出格式】
一行一个正整数。
【输入样例】
3 100
【输出样例】
981
【问题分析】
该系列实际上就是:k0,k1,k0+k1,k2,k0+k2,k1+k2,k0+k1+k2,… 所以,只要将n转换成二进制数a[i],然后求出所有a[i]不等于0的对应项ki之和。

#include<bits/stdc++.h>
using namespace std;
int a[10000];
int main(){
	int k,n,i;
	cin>>k>>n;
	i=0;
	do{
		a[++i]=n%2;
		n/=2;
	}while(n!=0);
	int x=1;
	int ans=a[1];
	for(int j=2;j<=i;j++){
		x*=k;
		ans+=a[j]*x;
	}
	cout<<ans<<endl;
	return 0;
}
	
实例巩固
1.乘法口诀表

输入一个自然数N(2<=N<=16),输出N进制乘法口诀表,请严格按照以格式输出:
大写字母、右对齐,除了最左列外,每个数据项占4列。以下是N=16时的结果:
* 0 1 2 3 4 5 6 7 8 9 A B C D E F
0 0
1 0 1
2 0 2 4
3 0 3 6 9
4 0 4 8 C 10
5 0 5 A F 14 19
6 0 6 C 12 18 1E 24
7 0 7 E 15 1C 23 2A 31
8 0 8 10 18 20 28 30 38 40
9 0 9 12 1B 24 2D 36 3F 48 51
A 0 A 14 1E 28 32 3C 46 50 5A 64
B 0 B 16 21 2C 37 42 4D 58 63 6E 79
C 0 C 18 24 30 3C 48 54 60 6C 78 84 90
D 0 D 1A 27 34 41 4E 5B 68 75 82 8F 9C A9
E 0 E 1C 2A 38 46 54 62 70 7E 8C 9A A8 B6 C4
F 0 F 1E 2D 3C 4B 5A 69 78 87 96 A5 B4 C3 D2 E1

2.完全平方回文数

【问题描述】
给定一个十进制自然数的范围和进制的范围,十进制自然数范围在144700之间,是m*m形成的平方数,进制的范围在236之间。给定范围里的数中,有些数的平方,在某进制下既是完全平方数,又是回文数。本题的任务是统计给定范围内有多少个数的平方满足下列条件;仅在某一进制下既是完全平方数又是回文数。
说明:32=9,因为它在十进制和十一进制中都是回文数,所以9不能算;同样,262=676也不算。
【输入格式】
一行四个整数,分别表示给定的十进制自然数m的范围和进制的范围。
【输出格式】
一行一个正整数,青示给定范围内满足条件的数的个数。
【输入样例】
1 100 9 11
【输出样例】
12
【样例说明】
6^2=36=33 base 11
10^2=100=121 base 9
11^2=121=121 base 10
12^2=144=121 base 11
20^2=400=484 base 9
22^2=484=484 base 10
24^2=576=484 base 11
72^2=5184=3993 base 11
82^2=6724=10201 base 9
84^2=7056=5335 base 11
91^2=8281=12321 base 9
100^2=10000=1464 base 9

3.罗马数字

【问题描述】
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。
【输入样例1】
3
【输出样例1】
III
【输入样例2】
9
【输出样例2】
IX
【输入样例3】
994
【输出样例3】
MCMXCIV

4.八进制小数

时光机

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值