黑客之都CSP-J模拟赛题解
T1:
题解:寻找峰值元素
思路分析
本题要求统计整数数组中峰值元素的个数。峰值元素定义为严格大于其左右相邻元素的元素。由于第一个和最后一个元素缺少一个相邻元素,因此它们不能是峰值元素。
解决方案是遍历数组(从第二个元素到倒数第二个元素),检查每个元素是否严格大于其左右相邻元素。如果满足条件,则计数器加1。
算法步骤
- 读取整数
n
,表示数组长度。 - 读取
n
个整数,存入数组arr
。 - 初始化计数器
count
为 0。 - 遍历数组索引从 1 到
n-2
(即第二个元素到倒数第二个元素):- 如果当前元素
arr[i]
严格大于左邻居arr[i-1]
且严格大于右邻居arr[i+1]
,则count
增加 1。
- 如果当前元素
- 输出
count
。
复杂度分析
- 时间复杂度:O(n),需要遍历数组一次。
- 空间复杂度:O(n),用于存储数组。
代码实现(C++)
#include <iostream>
using namespace std;int main() {int n;cin >> n;int arr[n];for (int i = 0; i < n; i++) {cin >> arr[i];}int count = 0;for (int i = 1; i < n - 1; i++) {if (arr[i] > arr[i-1] && arr[i] > arr[i+1]) {count++;}}cout << count << endl;return 0;
}
测试点验证
- 测试点1:输入
[1, 2, 1]
,输出1
,正确。 - 测试点2:输入
[1, 2, 3, 4]
,输出0
,正确。 - 测试点3:输入
[1, 3, 1, 3, 1]
,输出2
,正确。 - 测试点4:输入
[2, 2, 2, 2, 2]
,输出0
,正确。 - 测试点5:输入
[1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
,输出4
,正确。
T2:
C++ 解法:正数子序列计数
为了解决这个问题,我们需要计算给定数字序列中所有和为正数的连续子序列的数量。连续子序列是指序列中连续的一段元素组成的子序列。我们可以通过枚举所有可能的连续子序列,并检查它们的和是否为正数来解决这个问题。
方法思路
- 问题分析:我们需要统计所有连续子序列中,和为正数的子序列个数。由于序列长度最大为1000,我们可以使用双重循环来遍历所有可能的子序列。
- 算法选择:使用外层循环遍历每个可能的子序列起始位置,内层循环遍历从起始位置开始的所有可能的结束位置。在内层循环中,累加当前子序列的元素和,并判断是否为正数。
- 复杂度分析:该算法的时间复杂度为O(n²),其中n是序列的长度。对于n=1000来说,这是可行的。
解决代码
#include <iostream>
#include <vector>
using namespace std;int main() {int n;cin >> n;vector<int> arr(n);for (int i = 0; i < n; i++) {cin >> arr[i];}int count = 0;for (int i = 0; i < n; i++) {int current_sum = 0;for (int j = i; j < n; j++) {current_sum += arr[j];if (current_sum > 0) {count++;}}}cout << count << endl;return 0;
}
代码解释
- 输入处理:首先读取序列的长度
n
,然后读取序列元素并存储在向量arr
中。 - 初始化计数器:
count
用于记录和为正数的子序列数目,初始化为0。 - 双重循环:外层循环变量
i
表示子序列的起始索引,内层循环变量j
表示从i
到序列末尾的结束索引。 - 累加和检查:在内层循环中,累加当前子序列的元素和到
current_sum
。如果current_sum
为正数,则增加计数器count
。 - 输出结果:循环结束后,打印计数器
count
的值,即和为正数的子序列总数。
这种方法确保了我们能够高效地检查所有可能的连续子序列,并统计满足条件的子序列数目。