2021年信奥赛C++提高组csp-s初赛真题及答案解析(阅读程序第2题)

2021年信奥赛C++提高组csp-s初赛真题及答案解析(阅读程序第2题)

第2题
cpp 复制代码
01 #include <algorithm>
02 #include <iostream>
03 using namespace std;
04 
05 int n, a[1005];
06 
07 struct Node
08 {
09    int h, j, m, w;
10 
11    Node(const int _h, const int _j, const int _m, const int _w):
12   	 h(_h), j(_j), m(_m), w(_w)
13    {	}
14 
15    Node operator+(const Node &o) const
16    {
17    	return Node(
18    		max(h, w + o.h),
19    		max(max(j, o.j), m + o.h),
20   		 max(m + o.w, o.m),
21   		 w + o.w);
22    }
23 };  
24 
25 Node solve1(int h, int m)
26 {
27     if (h > m)
28     		return Node(-1, -1, -1, -1);
29     if (h == m)
30     		return Node(max(a[h], 0), max(a[h], 0), max(a[h], 0), a[h]);
31     int j = (h + m) >> 1;
32     		return solve1(h, j) + solve1(j + 1, m);
33 }
34 
35 int solve2(int h, int m)
36 {
37     if (h > m)
38     		return -1;
39     if (h == m)
40     		return max(a[h], 0);
41     int j = (h + m) >> 1;
42     int wh = 0, wm = 0;
43     int wht = 0, wmt = 0;
44     for (int i = j; i >= h; i--){
45     		wht += a[i];
46     		wh = max(wh, wht);
47     }		
48     for (int i = j + 1; i <= m; i++){
49     		wmt += a[i];
50     		wm = max(wm, wmt);
51     }
52     return max(max(solve2(h, j), solve2(j + 1, m)), wh + wm);
53 }
54 
55 int main()
56 {
57     cin >> n;
58     for (int i = 1; i <= n; i++) cin >> a[i];
59     cout << solve1(1, n).j << endl;
60     cout << solve2(1, n) << endl;
61     return 0;
62 }

假设输入的所有数的绝对值都不超过 1000 ,完成下面的判断题和单选题:

判断题
  1. 程序总是会正常执行并输出两行两个相等的数。( )

    A. 正确 B. 错误

  2. 第 28 行与第 38 行分别有可能执行两次及以上。( )

    A. 正确 B. 错误

  3. 当输入为 5 -10 11 -9 5 -7 时,输出的第二行为 7。( )

    A. 正确 B. 错误

单选题
  1. solve1(1, n) 的时间复杂度为( )。
    A. O(log⁡n)
    B. O(n)
    C. O(nlog⁡n)
    D. O( n 2 n^2 n2)
  2. solve2(1, n) 的时间复杂度为( )。
    A. O(log⁡n)
    B. O(n)
    C. O(nlog⁡n)
    D. O( n 2 n^2 n2)
  3. 当输入为 10 -3 2 10 0 -8 9 -4 -5 9 4 时,输出的第一行为( )。
    A. 13
    B. 17
    C. 24
    D. 12

题目代码分析

程序包含两个分治函数 solve1solve2,均用于求解允许空子段的最大子段和(即当所有元素为负时结果为 0)。

  • solve1 采用经典的分治合并法,结构体 Node 存储区间的四个关键信息:前缀最大和(h)区间最大子段和(j)后缀最大和(m)区间总和(w) 。合并操作 operator+ 可在 O(1) 内完成。
  • solve2 同样分治,但合并时通过两个循环分别求左半部分的最大后缀和右半部分的最大前缀和,合并代价与区间长度成正比。

判断题答案及解析
  1. 程序总是会正常执行并输出两行两个相等的数。

    • 当 (n \ge 1) 时,两函数均递归计算最大子段和,结果相等且非负。
    • 当 (n = 0) 时,solve1(1,0) 执行第 28 行返回 Node(-1,-1,-1,-1).j = -1solve2(1,0) 执行第 38 行返回 -1。输出均为 -1,仍相等。
    • 程序无崩溃风险,递归深度仅 (\log n),数组范围安全。故总是输出两个相等的数
      答案:A
  2. 第 28 行与第 38 行分别有可能执行两次及以上。

    • 递归过程中,划分区间 j = (h+m)>>1 保证左右子区间均非空(当 h < m 时,j ≥ hj < m)。因此内部递归不会出现 h > m 的情况。
    • 仅当初始调用 h > m(如 n = 0)时,各执行一次 。不可能执行两次或以上。
      答案:B
  3. 当输入为 5 -10 11 -9 5 -7 时,输出的第二行为 7

    • 数组:-10, 11, -9, 5, -7
    • 最大子段和显然是单独元素 11(或 11 -9 +5 = 7 更小),故结果应为 11
    • 第二行是 solve2 的输出,应为 11,而非 7
      答案:B

单选题答案及解析
  1. solve1(1, n) 的时间复杂度

    • 递归式 (T(n) = 2T(n/2) + O(1)),合并操作为常数时间。由主定理,时间复杂度为 O(n)
      答案:B
  2. solve2(1, n) 的时间复杂度

    • 递归式 (T(n) = 2T(n/2) + O(n))(两个循环各扫描半个区间),由主定理,时间复杂度为 O(n log n)
      答案:C
  3. 当输入为 10 -3 2 10 0 -8 9 -4 -5 9 4 时,输出的第一行

    • 数组:-3, 2, 10, 0, -8, 9, -4, -5, 9, 4
    • 枚举连续子段,最大和为 2 + 10 + 0 -8 + 9 -4 -5 + 9 + 4 = 17(下标 2~10)。
    • solve1(1,n).j 即此最大子段和,结果为 17
      答案:B

专栏推荐:信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新)
https://blog.csdn.net/weixin_66461496/category_13125089.html


各种学习资料,助力大家一站式学习和提升!!!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"##########  一站式掌握信奥赛知识!  ##########";
	cout<<"#############  冲刺信奥赛拿奖!  #############";
	cout<<"######  课程购买后永久学习,不受限制!   ######";
	return 0;
}

1、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html

2、csp信奥赛冲刺一等奖有效刷题题解:

CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新):https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

CSP信奥赛C++一等奖通关刷题题单及题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新)
https://blog.csdn.net/weixin_66461496/category_13125089.html

3、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html

4、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
生活很暖很治愈2 小时前
Linux——线程异常
linux·c++·ubuntu
生活很暖很治愈2 小时前
Linux——线程概念&控制&创建&等待
linux·服务器·c++·ubuntu
REDcker2 小时前
FFmpeg完整文档
linux·服务器·c++·ffmpeg·音视频·c·后端开发
你好!蒋韦杰-(烟雨平生)2 小时前
opengl阴影实现
c++·数学·游戏·3d
仰泳的熊猫2 小时前
题目 1473: 蓝桥杯基础练习VIP-芯片测试
数据结构·c++·算法·蓝桥杯
小冻梨6662 小时前
ABC444 - C 翻译
c++
拳里剑气2 小时前
C++:封装红黑树实现map和set
开发语言·数据结构·c++·学习方法
汉克老师2 小时前
GESP2024年9月认证C++二级( 第一部分选择题(1-8))
c++·算法·循环结构·分支结构·gesp二级·gesp2级
阿猿收手吧!2 小时前
【C++】syncstream:多线程安全输出的终极方案
c++·安全