2023 CSP-J详解

csp 崩了,滚来写题解,悄悄话,我服了今年这么简单我竟然崩了(蒟蒻石锤)
话不多,来吧上题目
原谅我上来就用四级标题

一.

T1.

1.在C++中,下面那个关键字用于声明一个变量,其值不能被修改?()

A. unsigned
B. const
C.static
D.mutable

这个题不用我多说吧,有点常识就知道

A.无符号性
B.定义常量(不可修改)
C.静态变量
D.可修改变量

T2.

  1. 八进制数12345670和07654321的和是()

原谅我不会打脚标
A.八进制22222221
B.八进制21111111
C.八进制22111111
D.八进制22222211

这个不多讲了,不会可以去查查八进制加减,选D

T3.

3.阅读下列代码,请问修改 data 的 value 成员以储存 3.14,正确的方式是()

union Data{
    int num;
    float value;
    char symbol;
};
union Data data;

A. data.value = 3.14;
B. value.data = 3.14;
C. data->value = 3.14;
D. value->data= 3.14;

普及一下:union是联合体,和struct类似吧,->这个玩意是指针用的。

选A

T4.

假设有一个链表的节点定义如下

struct node{
    
    int data;
    Node*next;
}

现在有一个指向头部的指针:Node* head。如果想要在链表中插入一个点,其成员 data 的值为42,并使新节点成为链表的第一个节点,下面哪个操作是正确的()

A.Node* newNode = newNode;
newNode->data = 42; newNode->next = head; head = newNode;
B. Node* newNode = new Node; head->data = 42; newNode -> next = head; head = newNode;

C.Node* newNode = new Node; newNode -> data = 42; head->next = newNode;

D.Node* newNode = new Node; newNode -> data = 42; newNode->next = head;

还好考试之前练了练数据结构( * * )
7a64115268ef215082bcb3f952f5cced.png

//悄悄写了一下数据结构的博客

void add_to_head(int x) {
    e[idx] = x; ne[idx] = head; 
    head = idx; 
    idx ++; }
    //将 X 插入头节点的位置

数据结构博客

T5.

5.根节点的高度为1, 一棵拥有2023个节点的三叉树高度至少是()

A. 6
B. 7
C. 8
D. 9

和二叉树打交道这么多年,突然来个三叉树有点懵

一棵满三叉树的节点数是$
(3^n-1)/2$ 所以第2023个节点在 7 — 8层之间,至少是8层

T6.

  1. 小明在某一天中依次有七个空闲时间段,他想要至少一个空闲时间段来练习唱歌,但他希望任意两个练习的时间段之间都有智商两个空闲的时间段让他休息。则小明共有()种时间段的选择方案

A.31
B.18
C.21
D.33

认识我的都知道,我的特长是组合数学( * * )

选一个有7种情况,选两个有10种情况,选三个只有一种情况。

T7.

  1. 以下关于高精度运算的说法错误的是()

A. 高精度计算主要是用来处理大整数或者需要保留多位小数的运算
B.大整数除以小整数的处理的步骤可以是,将被除数和除数对齐,从左到右逐位尝试将除数乘以某个数通过减法得到新的被除数,并累加商
C.高精度的乘法的的运算时间只和参与运算的两个整数中的长度较长的位数有关
D.高精度加法运算的关键在于逐位相加并处理进位

这个题蒙也蒙对了
C太绝对了 ( * * )

高精度乘法的时间复杂度难道不是和两个字符串长度的乘积有关???

T8.

后缀表达式“623+-382/+*2^3+”对应的中缀表达式是()

A.((6-(2+3))*(3 + 8 / 2))^2 + 3
B.6 - 2 + 3 * 3 + 8 / 2 ^ 2 + 3
C.(6-(2 + 3)) * ((3 + 8 / 2 ^ 2) ^ 2) + 3
D.6-((2 + 3) * (3 + 8 / 2)) ^ 2 + 3

后缀表达式转中缀表达式不多说了,实在不会网络上比比皆是讲的都比我好

T9.

二进制数 101010 和 八进制数166的和是()

必须吐槽一下,今年的题是想逼着我把计算搞好吗???
A. 10110000 (二进制)
B. 236(八进制)
C. 158(十进制)
D. A0 (十六进制)

进制转换不多说,选D

10

假设有一组字符串{a, b, c, d, e, f} 对应的频率分别是 5%,9%,12%,16%,45%,请问下面哪一个选项是字符a, b, c, d, e, f分别对应的一组哈夫曼编码?()

A.1111 1110 101 100 011 0
B. 1010 1001 1000 011 010 00
C. 000 001 010 011 10 11
D. 1010 1011 110 111 00 01

这个题还原哈夫曼树啊,我傻了,还原错了(敲死)选了个看起来差不多的……

寻找集合T中权值最小的两个节点;使用两个权值最小的节点构建新的节点;

选 A

11

给定一棵二叉树,其前序遍历结果是 ABDECFG, 中序遍历结果是:DEBACFG
请问这棵树的后序遍历是什么?

这个题的选项有问题,等我找到更改后的选项哈

这个题考的是根据二叉树的前序遍历和中序遍历构造二叉树。

其实就是先根据前序遍历的下标为零的就是根节点。

话不多说上链接
根据前序遍历和中序遍历构造二叉树

12

考虑一个有向无环图,改图包含四条有向边:(1,2)(1,3)(2,4)(3,4),以下哪个选项是这个有向无环图的一个有效的拓扑排序?()

A. 4, 2, 3. 1
B. 1, 2, 3, 4
C. 2, 1, 3, 4
D. 2, 1, 4 ,3

  1. 从 DAG 图中选择一个 没有前驱(即入度为0)的顶点并输出。
  2. 从图中删除该顶点和所有以它为起点的有向边。
  3. 重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止。后一种情况说明有向图中必然存在环。
    综上所述,只有可能是 1 - 2 - 3 - 4或者 1 - 3 - 2 - 4

选B

13

在计算机中,以下哪个选项描述的数据储存容量最小?()

A.字节(byte)
B.比特(bit)
C.字(word)
D.千字节(kilobyte)

bit不是储存数据的啊!!!

选A

14

14.一个班级有10个男生和12个女生。如果要选出一个3人小组,并且必须至少包含一个女生,那么有多少种可能的组合?()

A.1420
B.1770
C.1540
D.2200

还是那句话,组合数学是我的专长啊,这个题我实话实说手算的,如果需要步骤,评论区告诉我,我看到了会补充的。

分类讨论
算出选一个女生有多少种,选两个女生有,三个女生有,然后加起来(因为打草纸被回收了,我也忘了具体多少,改天有空再算算)
手算1420

15

以下哪个不是操作系统

A.Linux
B.Window
C.Android
D.HTML

常识题不讲 选D

二.

(1)

#include <bits/stdc++.h>

using namespace std;

double f(double a, double b, double c){
	double s = (a + b + c) /2;
	return sqrt(s * (s - a) * (s - b) * (s - c));
}

int main()
{
	cout.flags(ios::fixed);//精度控制
	cout.precision(4);// 保留4位小数
	
	int a, b, c;
	cin >> a >> b >> c;
	
	cout << f(a, b, c) << endl;
	return 0;
}
程序分析

其实这段代码非常的令人欣喜,非常简单易懂,只要上了初二就知道 函数 f是海伦公式,不知道也没事 小模拟就能渡劫

·判断题

当输入为“2 2 2”时,输出为“1.7321”。()

说真的,初二学好平方根(好像是初二吧(ˇˍˇ) 想~)真的有用哎,出考场一堆人在问根号三是多少,我非常肯定是1.7321…

将第七行的“(s - b) * (s - c)”改为“(s - c) * ( s - b)”不会影响程序

当然不会, 根号a * b = 根号 b * a

程序总能输出四位小数

呵呵,你猜为什么,当然是11 12行控制精度和输出保留4位了啊

·选择题

不讲了,手动模拟一下,带入 a b c 的只就行了

(2)

#include <bits/stdc++.h>

using namespace std;

int f(string x, string y)
{
	int m = x.size();
	int n = y.size();
	vector<vector<int>> v(m + 1, vector<int>(n + 1, 0));
	for(int i = 1; i <= m; i ++)
	{
		for(int j = 1; j <= n; j ++)
		{
			if(x[i - 1] == y[j - 1])
			{
				v[i][j] = v[i - 1][j - 1] + 1;
			}
	        else
			{
				v[i][j] = max(v[i - 1][j], v[i][j - 1]);
			}
		}
	}
 return v[m][n];
}

bool g(string x, string y)
{
	if(x.size() != y.size()){
		return false;
	}
	return f(x + x, y) == y.size();
}
int main()
{
	string x, y;
	cin >> x >> y;
	cout << g(x, y) << endl;
	return 0;
}
·程序分析

两个相同长度的字符串, 将第一个字符串复制并加到自己的结尾处,求最长公共字段长后判断是不是和第二个字符串长度相同,相同输出1

·判断题

f 函数的返回小于等于 min(n, m)

f函数求的是string x 和string y 的最长公共子串的长度,所以肯定是小于等于 min(n, m)

f函数返回值等于输入两个字符串的最长公共子串的长度

肯定不对啊,是求的第一个字符串复制一次和第二个字符串的最长公共子串

当输入两个完全相同的字符串时,g函数返回值永远是 true

这个当然啦,举个例子 abc abc 吧,复制后是 abcabc abc 最长公共子串是 abc 吧,肯定等于第二个字符串啊

·单选题

将第19行中的“v[m][n]”替换成“v[n][m]”那么该程序()

A 行为不变
B 只会改变输出
C 一定非正常退出
D 可能非正常输出

换了之后有什么后果呢???当然是 vector数组可能越界

当输入是“csp-j p-jcs”时输出是()

A 0
B 1
C T
D F

模拟一下 csp-j复制后是csp-jcsp-j
返回true 即输出是 1

26题同上模拟

输出1

继续鸽了

posted @ 2023-09-17 21:23  Auditorymoon  阅读(684)  评论(0)    收藏  举报