CSP-202109-2-非零段划分

2024-03-01 11:52
文章标签 csp 划分 202109 非零段

本文主要是介绍CSP-202109-2-非零段划分,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

CSP-202109-2-非零段划分

【70分思路-暴力枚举】

这段代码的目的是在给定一个由自然数(非负整数)组成的数组后,通过选择一个适当的正整数 p,将数组中所有小于 p 的数变为 0,从而使得数组中非零段的数量达到最大。这里的非零段是指连续的、非零的数组元素序列。

程序的主要逻辑分为以下几个步骤:

  1. 读取数组长度 n 和数组元素,同时找出数组中的最大元素 maxElem。

  2. 对于每一个可能的 p 值(从 1 到 maxElem),复制原始数组并将所有小于 p 的元素设置为 0。

  3. 对于每个 p 值的新数组,遍历数组来计算非零段的数量。一个非零段开始于一个非零元素,该元素要么是数组的第一个元素,要么其前一个元素为零。非零段结束于数组的最后一个元素或一个非零元素后跟着一个零元素。

  4. 更新并记录非零段数量的最大值。

  5. 输出非零段的最大数量。

时间复杂度

  1. 第一层循环(读取数组)的时间复杂度为 O(n),n 是数组的长度。

  2. 第二层循环是对于每一个可能的 p 值进行迭代,其最坏情况下的时间复杂度为 O(maxElem)。

  3. 在每一个 p 的值下,我们又对数组进行了两次遍历(一次是将小于 p 的值置为 0,另一次是计算非零段的数量),每次遍历的时间复杂度为 O(n)。

因此,整个程序的总时间复杂度为 O(maxElem * n),这里 maxElem 是数组中的最大值,n 是数组的长度。由于 maxElem 可能接近 n,所以在最坏情况下,时间复杂度可以近似为 O(n^2)。

#include <iostream>    
#include <vector>
#include <algorithm>
using namespace std;
vector<int>arr;int main() {long long n;int maxNum = -1, maxElem = -1;cin >> n;for (int i = 0; i < n; i++){int t;cin >> t;arr.push_back(t);maxElem = max(maxElem, t);}for (int p = 1; p <= maxElem; p++){// 小于 p 的数都变为 0for (auto& it : arr) {if (it < p) it = 0;}int num = 0;bool flag = 1; // 1-上一位是0;0-上一位不是零// 统计非零段for (auto& it : arr) {if (it != 0) {if (flag) {num++;}flag = 0;}else{flag = 1;}}// 记录最大非零段数maxNum = max(maxNum, num);}cout << maxNum;return 0;
}

【100分思路-差分数组】

  1. 初始化和输入处理:定义了两个向量numbersdiff,分别用于存储输入的数列和差分数组。numbers的大小比实际数列长度多2,这是为了在数列的开始和结束添加边界值0,以方便处理。

  2. 去重和边界处理:使用unique函数去除连续重复元素,这对于减少不必要的计算特别有效,因为连续的相同数值不会增加非零段的数量

  3. 差分数组的构建:

    • 差分数组diff用于记录每个可能的数值对应的变化(峰值增加,谷值减少)。这实际上是对数列进行一种“转化”,使得后续的求解更加直接和高效。
    • 遍历数列,如果当前数字是一个峰值(即比前一个和后一个数都大),则在差分数组对应位置加一;如果是谷值(即比前一个和后一个数都小),则减一。
  4. 通过差分数组求解答案:

    • 通过遍历差分数组的累加和(即从后向前计算前缀和),可以找出使非零段数量最大化的数值。这是因为差分数组的前缀和反映了在当前阈值下,非零段的增减情况。

时间复杂度

  • 初始化和输入处理:O(N),其中N是数列的长度。
  • 去除连续重复元素:最坏情况下O(N),因为需要检查每个元素是否与前一个相同。
  • 构建差分数组:O(N),每个元素至多被访问一次。
  • 通过差分数组求解答案:O(V),其中V是数值的最大可能值,这里是MAX_VALUE
  • 因此,总体时间复杂度为O(N + V),其中N是数列的长度,V是数值的最大可能范围。
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring> 
using namespace std;const int MAX_NUM = 500000; // 最大数字数量
const int MAX_VALUE = 10000; // 最大值
vector<int> numbers(MAX_NUM + 2); // 使用vector存储输入的数列
vector<int> diff(MAX_VALUE + 1); // 使用vector存储差分数组int main() {int length;cin >> length;for (int i = 1; i <= length; i++) {cin >> numbers[i];}numbers[0] = numbers[length + 1] = 0; // 将边界设置为0// unique函数去除连续重复元素,更新vector的有效长度length = unique(numbers.begin(), numbers.begin() + length + 2) - numbers.begin() - 1;// 初始化差分数组为0fill(diff.begin(), diff.end(), 0);for (int i = 1; i < length; i++){if (numbers[i - 1] < numbers[i] && numbers[i] > numbers[i + 1]) {diff[numbers[i]]++; // 如果是峰值,对应的差分数组加一}else if (numbers[i - 1] > numbers[i] && numbers[i] < numbers[i + 1]) {diff[numbers[i]]--; // 如果是谷值,对应的差分数组减一}}// 通过差分数组求解答案int maxSegments = 0, sum = 0; // maxSegments记录最终答案,sum记录差分的前缀和for (int i = MAX_VALUE; i >= 1; i--) {sum += diff[i]; // 累加差分得到前缀和maxSegments = max(maxSegments, sum); // 更新答案}cout << maxSegments << endl; return 0;
}

请添加图片描述

这篇关于CSP-202109-2-非零段划分的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/762366

相关文章

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

Golang的CSP模型简介(最新推荐)

《Golang的CSP模型简介(最新推荐)》Golang采用了CSP(CommunicatingSequentialProcesses,通信顺序进程)并发模型,通过goroutine和channe... 目录前言一、介绍1. 什么是 CSP 模型2. Goroutine3. Channel4. Channe

poj 2104 and hdu 2665 划分树模板入门题

题意: 给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。 解析: 划分树入门。 bing神的模板。 坑爹的地方是把-l 看成了-1........ 一直re。 代码: poj 2104: #include <iostream>#include <cstdio>#include <cstdlib>#include <al

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

Thread如何划分为Warp?

1 .Thread如何划分为Warp? https://jielahou.com/code/cuda/thread-to-warp.html  Thread Index和Thread ID之间有什么关系呢?(线程架构参考这里:CUDA C++ Programming Guide (nvidia.com)open in new window) 1维的Thread Index,其Thread

CSP-J基础之数学基础 初等数论 一篇搞懂(一)

文章目录 前言声明初等数论是什么初等数论历史1. **古代时期**2. **中世纪时期**3. **文艺复兴与近代**4. **现代时期** 整数的整除性约数什么样的整数除什么样的整数才能得到整数?条件:举例说明:一般化: 判断两个数能否被整除 因数与倍数质数与复合数使用开根号法判定质数哥德巴赫猜想最大公因数与辗转相除法计算最大公因数的常用方法:举几个例子:例子 1: 计算 12 和 18

CSP-J基础之数学基础 初等数论 一篇搞懂(二)

文章目录 前言算术基本定理简介什么是质数?举个简单例子:重要的结论:算术基本定理公式解释:举例: 算术基本定理的求法如何找出质因数:举个简单的例子: 重要的步骤:C++实现 同余举个例子:同余的性质简介1. 同余的自反性2. 同余的对称性3. 同余的传递性4. 同余的加法性质5. 同余的乘法性质 推论 总结 前言 在计算机科学和数学中,初等数论是一个重要的基础领域,涉及到整数

CSP-J基础之cmath常见函数

文章目录 前言1. **`sin` 函数**2. **`cos` 函数**3. **`exp` 函数**4. **`log` 函数**5. **`fabs` 函数**6. **`pow` 函数**7. **`sqrt` 函数**8. **`ceil` 函数**9. **`floor` 函数** 总结 前言 在计算机科学与编程中,数学函数是解决各种计算问题的基础工具。C++标准

CSP-J选择题 - 排列组合

排列问题:有5名学生参加比赛,要求排成一排拍照,有多少种不同的排列方式?组合问题:从10本书中选出3本书送给朋友,有多少种不同的选择方式?排列问题:一个教室有7个座位,5个学生需要坐下,有多少种不同的排列方式?组合问题:从12个人中选出4个人组成一个团队,有多少种不同的方式?排列问题:一个密码由4个字母组成,字母可以重复使用,有多少种不同的排列组合?组合问题:从8个不同颜色的球中选出3个,不考虑顺

【电子通识】洁净度等级划分及等级标准

洁净度常用于评估半导体、生物制药、医疗、实验室及科研院所、新能源等领域的洁净室、无尘室或者无菌室等环境。         一般来说,晶圆光刻、制造、测试等级为100级或1000级的洁净间,百级洁净间要求空气中0.5微米的尘埃粒子数不得超过每立方米3520个;等级为1000级的洁净间要求0.5微米的尘埃粒子数不得超过每立方米35200个。         晶圆切割或封装工序一