CSP-J/S初赛 域 JT23 CSP-J真题2023

选择部分

4.假设有一个链表的节点定义如下: struct Node { int data; Node* next; }现在有一个指向链表头部的指针:Node* head。如果想要在链表中插入一个新节点,其成员 data 的值为42,并使新节点成为链表的第一个节点,下面哪个操作是正确的?

7..以下关于高精度运算的说法错误的是(高精度乘法的运算时间只与参与运算的两个整数中长度较长者的位数有关)

举例 1 35353x9和35353x3856 第二个时间更长,说法错误

10.假设有一组字符 {a,b,c,d,e,f}, 对应的频率分别为5%,9%,12%,13%,16%,45%。请问以下哪个选项是字符abcdef分别对应的一组哈夫曼编码?1111,1110,101,100,110,0

建立哈夫曼树

11.给定一棵二叉树,其前序遍历结果为:ABDECFG,中序遍历结果为:DEBACFG。请问这棵树的正确后序遍历结果是什么(EDBGFCA)

二叉树:

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

当含有一个女生时,有12*(109)/(21)=540种

当含有两个女生时,有(1211)/(12)*10=660种

当含有三个女生时,有(121110)/(123)=220种

共有220+660+540=1420种

15.以下哪个不是操作系统?(HTML)

计算机常识

阅读程序

##(2)

#include<iostream>
#include<vector>
#include<algorithm>
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;
}

代码作用判断y是不是x x的最长公共子序列

22. 函数的返回值等于两个输入字符串的最长公共子串的长度(F)

函数的返回值等于两个输入字符串的最长公共子序列,这是对的;

23.当输入两个完全相同的字符串时,g 函数的返回值总是 true(T)

因为当输入两个完全相同的字符串时,y一定是xx的最长公共子序列

(3)

#include <iostream>
#include <cmath>
using namespace std;

int solve1(int n){
	return n*n;
}
int solve2(int n){
	int sum=0;
	for(int i=1;i<=sqrt(n);i++){
		if(n%i==0){
			if(n/i==i){
				sum+=i*i;
			}else{
				sum+=i*i+(n/i)*(n/i);
			}
		}
	}
	return sum;
}
int main(){
	int n;
	cin>>n;
	cout<<solve2(solve1(n))<<" "<<solve1((solve2(n)))<<endl;
	return 0;
}

代码是求n*n的所有约数的平方和 和

30.如果输入的 n 为质数 p 的平方,那么 solve2(n) 的返回值为(nn+n+1)求nn的所有约数的平方和

代码solve2函数是求n的所有约数的平方和,该题中n的约数有1,p,n; solve2(n) 的返回值为(11+pp+nn=nn+n+1)

补代码

(1)

#include <iostream>
#include <vector>
using namespace std;
int find_missing(vector<int>& nums) {
	int left = 0, right = nums.size() - 1;
	while (left < right){
		int mid = left + (right - left) / 2;
		if (nums[mid] == mid + nums[0]) {
		left=mid+1;
		} else {
			right=mid;
		}
	}
	return left+nums[0];
}
int main() {
	int n;
	cin >> n;
	vector<int> nums(n);
	for (int i = 0; i < n; i++) cin >> nums[i];
	int missing_number = find_missing(nums);
	if (missing_number == nums[0]+n+1) {
		cout << "Sequence is consecutive" << endl;
	}else{
		cout << "Missing number is " << missing_number << endl;
	}
	return 0;
}

代码是用来寻找被移除的元素的

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int min(int x, int y, int z) {
	return min(min(x, y), z);
}
int edit_dist_dp(string str1, string str2) {
	int m = str1.length();
	int n = str2.length();
	vector<vector<int>> dp(m + 1, vector<int>(n + 1));
	for (int i = 0; i <= m; i++) {
		for (int j = 0; j <= n; j++) {
			if (i == 0)
				dp[i][j] = j;
			else if (j == 0)
				dp[i][j] = i;
			else if (str1[i-1]==str2[j-1])
				dp[i][j] = dp[i-1][j-1];
			else
				dp[i][j] = 1 + min(dp[i][j - 1], dp[i - 1][j], dp[i-1][j-1]);
		}
	}
	return dp[m][n];
}
int main() {
	string str1, str2;
	cin >> str1 >> str2;
	cout << "Mininum number of operation:" << edit_dist_dp(str1, str2) << endl;
	return 0;
}

这个代码是给定两个字符串,每次操作可以选择删除(Delete)、插入(Insert)、替换(Replace),一个字符,求将第一个字符串转换为第二个字符串所需要的最少操作次数