数及其运算与进制转换
数及其运算与进制转换
自然数、整数、有理数、实数及其算术运算(加、减、乘、除);进制与进制转换:二进制、八进制、十进制、十六进制。
概念
这一叶子关心数的种类与表示,而不是数论里的整除或组合计数。自然数、整数、有理数、实数各是什么范围,四则运算在什么范围内仍封闭,是选择题常考的背景知识。进制转换是另一块重点:同一数值可以用不同基数写下,二进制、八进制、十进制、十六进制之间要能互化;带下标的写法(如 10112、D16)表示「这是几进制下的数」。与 cspj.math.number-theory 的区别在于:这里考怎么写、怎么换算,不考质因数分解或欧几里得算法;与 cspj.basics.computer-composition 相邻——位、字节是硬件单位,本叶子是数学上的进制。
CSP-J 常考
cspj-r1-2020第 9 题:二进制 1011 化为十进制(单选)。cspj-r1-2021第 7 题:带小数的二进制 101.11 对应的十进制值。cspj-r1-2024第 2 题:八进制减二进制再乘十六进制,求十进制结果(混合运算)。cspj-r1-2025第 13 题:十进制 720 与八进制 270 相加,结果用十六进制表示。cspj-r2-2020第 1 题(优秀的拆分):判断 n 能否拆成若干个互不相同的 2 的正整数次幂之和——本质是读 n 的二进制表示里哪些位为 1。
// 十进制 n 转为 b 进制字符串(b=2,8,16 等,digits 为各数位字符)
string toBase(int n, int b) {
if (n == 0) return "0";
const char* digits = "0123456789ABCDEF";
string s;
while (n) { s += digits[n % b]; n /= b; }
reverse(s.begin(), s.end());
return s;
}
易错点
- 混合进制表达式要先统一成十进制再算,不要把 148 当成十进制的 14。
- 二进制小数:小数点后第 k 位权值是 2−k,不是 2k。
- 十六进制字母 A–F 大小写题面可能混用,换算时按数值 10–15 处理。
- 完善程序里「字符转数字」常写
c - '0',那是十进制逐位读入,与二进制位权 2k 不是同一套空位。
二进制数 1011 转换成十进制数是( )。
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
原卷作答说明:判断题正确填 √,错误填 ×
#include <iostream>2using namespace std;34long long n, ans;5int k, len;6long long d[1000000];78int main() {9 cin >> n >> k;10 d[0] = 0;11 len = 1;12 ans = 0;13 for (long long i = 0; i < n; ++i) {14 ++d[0];15 for (int j = 0; j + 1 < len; ++j) {16 if (d[j] == k) {17 d[j] = 0;18 d[j + 1] += 1;19 ++ans;20 }21 }22 if (d[len - 1] == k) {23 d[len - 1] = 0;24 d[len] = 1;25 ++len;26 ++ans;27 }28 }29 cout << ans << endl;30 return 0;31}- 24判断1.5 分
若 k>1,则输出 ans 时,klen —定大于 n。( )
优秀的拆分
C++时间 1 s内存 256 MB 文件 IO:power.in → power.out
一般来说,一个正整数可以拆分成若干个正整数的和。
例如,1=1,10=1+2+3+4 等。对于正整数 n 的一种特定拆分,我们称它为“优秀的”,当且仅当在这种拆分下,n 被分解为了若干个不同的 2 的正整数次幂。注意,一个数 x 能被表示成 2 的正整数次幂,当且仅当 x 能通过正整数个 2 相乘在一起得到。
例如,10=8+2=23+21 是一个优秀的拆分。但是,7=4+2+1=22+21+20 就不是一个优秀的拆分,因为 1 不是 2 的正整数次幂。
现在,给定正整数 n,你需要判断这个数的所有拆分中,是否存在优秀的拆分。若存在,请你给出具体的拆分方案。
输入格式
从文件 power.in 中读入数据。
输入只有一行,一个正整数 n,表示需要判断的数。
输出格式
输出到文件 power.out 中。
若存在优秀的拆分,则从大到小输出拆分中的每一个数,相邻两个数之间用一个空格隔开。可以证明,在规定了拆分数字的顺序后,该拆分方案是唯一的。
若不存在优秀的拆分,输出 -1。
样例
6
4 2
6=4+2=22+21 是一个优秀的拆分。注意,6=2+2+2 不是一个优秀的拆分,因为拆分成的 3 个数不满足每个数互不相同。
7
-1
126
64 32 16 8 4 2
数据范围
对于 20% 的数据,n≤10。
对于另外 20% 的数据,保证 n 为奇数。
对于另外 20% 的数据,保证 n 为 2 的正整数次幂。
对于 80% 的数据,n≤1024。
对于 100% 的数据,1≤n≤1×107。
部分分
- 100 分
全部 20 个测试点等分;数据范围见 constraintsMd 各百分比档。
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB
判题结果
二进制数 101.11 对应的十进制数是( )。
八进制数 32.1 对应的十进制数是( )。
八进制数 123456708 和 076543218 的和为
数 1010102 和 1668 的和为 ( )
计算 (148−10102)×D16−11012 的结果,并选择答案的十进制值:( )
以下哪个序列对应数字 0 至 8 的 4 位二进制格雷码(Gray code)?( )
十进制数 72010 和八进制数 2708 的和用十六进制表示是多少?
整组作答后提交批改,成绩计入掌握度 · 已答 0/1
(1)(字符串解码)“行程长度编码”(Run-Length Encoding)是一种无损压缩算法,常用于压缩重复字符较多的数据,以减少存储空间。假设原始字符串不包含数字字符。压缩规则如下:i) 如果原始字符串中一个字符连续出现 N 次(N≥2),在压缩字符串中它被表示为“字符 + 数字 N”。例如,编码 A12 代表 12 个连续的字符 A。ii) 如果原始字符串中一个字符只出现 1 次,在压缩字符串中它就表示为该字符本身。例如,编码 B 代表 1 个字符 B。
以下程序实现读取压缩字符串并输出其原始的、解压后的形式。试补全程序。
#include <cctype>2#include <iostream>3#include <string>4using namespace std;56int main() {7 string z;8 cin >> z;9 string s = "";1011 for (int i = 0; i < z.length(); ) {12 char ch = z[i];1314 if (__①__ && isdigit(z[i + 1])) {15 i++;16 int count = 0;17 while (i < z.length() && isdigit(z[i])) {18 count = __②__;19 i++;20 }21 for (int j = 0; j < __③__; ++j) {22 s += ch;23 }24 } else {25 s += __④__;26 __⑤__;27 }28 }2930 cout << s << endl;31 return 0;32}- 34(②)单选空位 ②3 分
②处应填( )