CSP-J 2024 阅读程序一二三

答案版
考试时间:待定题型:阅读程序题 / 完善程序题题量:27题满分:100分课堂讲评 / LearnDash
一、阅读程序题

点击“显示答案”查看答案和解析。

(一)素数统计(1~5题)

C++ 程序代码

#include <iostream>using namespace std;bool isPrime(int n) {    if (n <= 1) return false;    for (int i = 2; i * i <= n; i++) {        if (n % i == 0) return false;    }    return true;}int countPrimes(int n) {    int count = 0;    for (int i = 2; i <= n; i++) {        if (isPrime(i)) count++;    }    return count;}int sumPrimes(int n) {    int sum = 0;    for (int i = 2; i <= n; i++) {        if (isPrime(i)) sum += i;    }    return sum;}int main() {    int x; cin >> x;    cout << countPrimes(x) << " " << sumPrimes(x) << endl;    return 0;}

程序功能

程序判断 2 到 n 之间的素数,并输出素数的个数和素数之和。

执行过程

  • isPrime 通过试除判断素数。
  • countPrimes 统计素数个数,sumPrimes 累加素数之和。

关键语句

i * i <= n 只检查到平方根,可以减少试除次数。

(二)费用动态规划(6~11题)

C++ 程序代码

#include <iostream>#include <vector>using namespace std;int compute(vector<int>& cost) {    int n = cost.size();    vector<int> dp(n+1, 0);    dp[1] = cost[0];    for (int i = 2; i <= n; i++) {        dp[i] = min(dp[i-1], dp[i-2]) + cost[i-1];    }    return min(dp[n], dp[n-1]);}int main() {    int n; cin >> n;    vector<int> cost(n);    for (int i = 0; i < n; i++) cin >> cost[i];    cout << compute(cost) << endl;    return 0;}

程序功能

程序用动态规划计算到达终点的最小累计费用。

执行过程

  • dp[i] 表示到达第 i 个位置的最小费用。
  • 状态转移为 dp[i] = min(dp[i-1], dp[i-2]) + cost[i-1]
  • 最后比较 dp[n]dp[n-1]

关键语句

dp[0]=0 是动态规划的边界条件。

(三)递归计算(12~17题)

C++ 程序代码

#include <iostream>#include <cmath>using namespace std;int customFunction(int a, int b) {    if (b == 0) return a;    return a + customFunction(a, b-1);}int main() {    int x, y; cin >> x >> y;    int result = customFunction(x, y);    cout << pow(result, 2) << endl;    return 0;}

程序功能

customFunction(a,b) 通过递归完成 a 的 b+1 次累加,主函数再求平方。

执行过程

  • b==0 时返回 a,递归结束。
  • 否则保留一个 a,并递归计算 customFunction(a,b-1)

关键语句

b 每次减 1;若 b 为负数,则无法到达终止条件。

二、完善程序

(一)判断平方数(18~22题)

C++ 程序代码

#include<iostream>#include<vector>using namespace std;bool isSquare(int num) {    int i = ***①***;    int bound = ***②***;    for (; i <= bound; ++i) {        if (***③***) {            return ***④***;        }    }    return ___⑤___;}int main() {    int n;    cin >> n;    if (isSquare(n)) {        cout << n << " is a square number" << endl;    } else {        cout << n << " is not a square number" << endl;    }    return 0;}

程序功能

程序判断 num 是否为完全平方数。

执行过程

  • 从 1 枚举到 floor(sqrt(num))
  • 若发现 num == i * i,返回 true。
  • 遍历结束仍未找到时返回 false。

关键语句

判断必须使用 ==,不能写成赋值符号 =

(二)汉诺塔问题(23~27题)

C++ 程序代码

#include <iostream>#include <vector>using namespace std;void move(char src, char tgt) {    cout << "从柱子" << src << "挪到柱子" << tgt << endl;}void dfs(int i, char src, char tmp, char tgt) {    if (i == ***①***) {        move(***②***);        return;    }    dfs(i - 1, ***③***);    move(src, tgt);    dfs(***⑤***, ***④***);}int main() {    int n;    cin >> n;    dfs(n, 'A', 'B', 'C');}

程序功能

程序用递归解决汉诺塔问题,把圆盘从 A 柱移动到 C 柱。

执行过程

  • 先把 i-1 个盘从 src 借助 tgt 移到 tmp。
  • 把最大盘从 src 移到 tgt。
  • 再把 i-1 个盘从 tmp 借助 src 移到 tgt。

关键语句

i==0 是递归终止条件。

答案汇总:1A,2B,3A,4B,5B;6A,7B,8B,9A,10B,11A;12B,13A,14A,15B,16B,17D;18A,19B,20D,21C,22D;23A,24B,25B,26B,27C。