PAT-Apat甲级题1007(python和c++实现)

PTA | 1007 Maximum Subsequence Sum

1007 Maximum Subsequence Sum

作者 CHEN, Yue

单位 浙江大学

Given a sequence of K integers { N1​, N2​, ..., NK​ }. A continuous subsequence is defined to be { Ni​, Ni+1​, ..., Nj​ } where 1≤i≤j≤K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.

Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.

Input Specification:

Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (≤10000). The second line contains K numbers, separated by a space.

Output Specification:

For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.

Sample Input:

10
-10 1 2 3 4 -5 -23 3 7 -21

Sample Output:

10 1 4

 万事开头难,先读题!

 

给定K个整数{ N1,N2,...,NK }。连续子序列被定义为{ Ni,Ni+1,...,其中1≤i≤j≤K。最大子序列(Maximum Subsequence)是一个连续的子序列,它具有最大的元素和。例如,给定序列{-2,11,-4,13,-5,-2 },其最大子序列为{ 11,-4,13 },最大和为20。

现在你应该找到最大的总和,以及最大子序列的第一个和最后一个数字。
输入规范:

每个输入文件包含一个测试用例。每种情况占两行。第一行包含正整数K(≤10000)。第二行包含K个数字,由空格分隔。
输出规格:

对于每个测试用例,在一行中输出最大和,以及最大子序列的第一个和最后一个数字。数字之间必须用一个空格隔开,但行尾不能有多余的空格。如果最大子序列不是唯一的,则输出具有最小索引i和j的子序列(如示例所示)。如果所有的K数都是负数,那么它的最大和被定义为0,你应该输出整个序列的第一个和最后一个数字。

由题目可以提取到以下关键信息:

        1, 给出指定长度的数组,一行输入长度,一行输入数组,最大长度是10000

        2, 要求的结果是:最大连续子数组的和以及这段子数组的起始位置和末尾位置,考虑是差分和前缀和的应用

        3, 如果是全负数数组,需要按照规定的输出规范进行输出

题目分析完之后,现在是手搓代码时间!!!

本题要求很简洁明了,即求最大的连续子数组和,在这里考虑使用差分与前缀和的思想对本题进行求解,同时又需要输出这段子数组的起始位置和末尾位置,因此首先定义两个变量用于记录这两个位置:head和tail,对输入数据进行处理,定义k用于接收数组的长度,对于C++,可以考虑定义长度为10001的数组用于存储,python的列表没有长度限制,因此只需要定于列表生成式对输入进行处理即可。

由于考虑使用差分和前缀和的思想解决本题,因此这里为了方便后续操作,分别对输入数组的下标0位置和前缀和数组的下标为零位置赋初值:0,使得前缀和数组中自下标位置起为“前 [i] 个子数组的和”,至于输入数组赋初值的原因,则是为了配合前缀和数组方便操作。

初始化代码和对于输入的处理部分如下:

python部分:

k = int(input()) # 接收输入
lst = [int(i) for i in input().split()] # 接收输入数组
lst.insert(0,0) # 输入数组下标为0位置赋初值0
sum_ = [0] * (len(lst)+1) # 生成前缀和数组,为了防止索引越界,一般考虑稍微初始化大一点点
for i in range(1, len(lst)):sum_[i] = sum_[i-1] + lst[i] # 计算前缀和数组

C++部分:

    cin >> k;// 接收输入sum_[0] = 0; // 前缀和数组初始值赋0for(int i=1;i<=k; i++){cin>> arr[i]; // 接收输入数组}for(int i=1; i<= k; i++){sum_[i] = sum_[i-1] + arr[i]; // 计算前缀和数组}

接下来是本题解题的核心部分,根据前缀和数组计算连续数组的最大和部分。

        由于初始化前缀和数组第一个元素为0,这里则直接从下标为1的位置开始操作,首先定义用于记录最大和的变量result,初始化为-1,这里因为全负数数组有规定的输出格式,且不需要其他额外的操作,因此为了遍历完前缀和数组后可以分辨出该数组是否为全负数数组,此处初始化为-1而不是0,因为全负数数组其子序列的和不可能为正数,但非全负数数组可能存在全零的情况,故此处不初始化为0,避免对后续造成干扰,细节处应该给予充分考虑,避免造成不必要的代码调试时间的浪费。

        此后,我们使用循环,遍历前缀和数组,初始化一个标记变量lowest,用于记录每次最长子数组发生变化后的起始部分,这里初始化为0,因为0下标对应的元素初始化为0,不纳入考虑,循环遍历时,应当使用前缀和数组的元素对下标为lowest的前缀和数组元素进行相减,比如:对于下标为i的前缀和数组sum[i],与标记位置元素sum[lowest] ,其差值为自下标lowest+1到下标为i这段子数组的和,得到这部分子数组的和,我们可以将其与result进行比较,只要发现结果大于result,则更新result,同时head更新为lowest+1,tail更新为i,即【head , tail】部分即为当前所遍历得到的最大连续子数组和,通过循环不断更新i的位置,最终将得到最大的连续子数组和result,以及其初始位置和结束位置下标,同时需要注意的是:标记lowest并不是一成不变的,需要在每次遍历的时候比较sum[i]以及sum[lowest]的大小,只要sum[i]比sum[lowest]小,则更新lowest的位置为i,这里也不难理解,当被减数sum[i]一定时,只有减数sum[lowest]最小,得到的差才能最大,也就是下标为lowest+1到i这部分子数组的和才能最大,这也是解决连续子数组问题的关键点之一。以下是这部分的代码实现:

python:

res = -1 # 最大连续子数组和
lowest = 0 # 标记位置
head = 0
tail = 0
for end in range(len(lst)):if sum_[end] - sum_[lowest] > res: # 当前计算结果大于之前计算得到的最大连续子数组和,更新res = sum_[end] - sum_[lowest]head = lowest + 1tail = endif sum_[lowest] > sum_[end]: # 保证减数最小lowest = end

C++:

// 初始化对应变量
int lowest=0,result=-1;
int head,tail;for(int end=1; end<=k; end ++){if(sum_[end] - sum_[lowest] > result){ // 当前计算得到的最大连续子数组和大于以前计算的result = sum_[end] - sum_[lowest];head = arr[lowest + 1];tail = arr[end];}if(sum_[lowest] > sum_[end]){ // 保证减数最小lowest = end;}
}

最后是完整的的代码部分:

C++:

#include<bits/stdc++.h>
using namespace std;int k;
int lowest=0,result=-1;
int head,tail;
int arr[1001],sum_[1001];int main(){cin >> k;// 接收输入sum_[0] = 0; // 前缀和数组初始值赋0for(int i=1;i<=k; i++){cin>> arr[i]; // 接收输入数组}for(int i=1; i<= k; i++){sum_[i] = sum_[i-1] + arr[i]; // 计算前缀和数组}for(int end=1; end<=k; end ++){if(sum_[end] - sum_[lowest] > result){result = sum_[end] - sum_[lowest];head = arr[lowest + 1];tail = arr[end];}if(sum_[lowest] > sum_[end]){lowest = end;}}if(result < 0){cout << 0 << " " << arr[1] << " " << arr[k];}else{cout << result << " " << head <<" " << tail;}
}

python:

k = int(input()) # 接收输入
lst = [int(i) for i in input().split()] # 接收输入数组
lst.insert(0,0) # 输入数组下标为0位置赋初值0
sum_ = [0] * (len(lst)+1) # 生成前缀和数组,为了防止索引越界,一般考虑稍微初始化大一点点
for i in range(1, len(lst)):sum_[i] = sum_[i-1] + lst[i] # 计算前缀和数组
res = -1
lowest = 0
head = 0
tail = 0
for end in range(len(lst)):if sum_[end] - sum_[lowest] > res:res = sum_[end] - sum_[lowest]head = lowest + 1tail = endif sum_[lowest] > sum_[end]:lowest = endif res < 0:print("0" + " " + str(lst[1]) + " " + str(lst[k]))
else:print(str(res) + " " + str(head) + " " + str(tail))

最后附上AK截图:

python

C++:

写在后面:

        本题题眼在于“最大连续子数组和”,一般此类题目的解题思路都在于“差分与前缀和”这块,构建前缀和数组,通过“被减数一定,减数最小,差值(最大连续子数组和)最大”思路来进行解题,本题难度适中,核心部分可以当作模板记忆。

        以上就是本题的全部内容,主要在于差分与前缀和思想的应用,对此还不清楚的童鞋可以去详细学习,当然如果您有需要,我可以出一期对于差分与前缀和讲解的文章或视频,您可以评论区留言,如果对于以上内容您有什么意见或建议,欢迎评论区交流!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/251258.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

论文阅读-MapReduce

论文名称&#xff1a;MapReduce: Simplified Data Processing on Large Clusters 翻译的效果不是很好&#xff0c;有空再看一遍&#xff0c;参照一下别人翻译的。 MapReduce:Simplified Data Processing on Large Clusters 中文翻译版(转) - 阿洒 - 博客园 (cnblogs.com) 概…

仰暮计划|“如果你想看到世界上最完美的笑容,你就要多一点儿时间跟老人在一起,老人笑了,你就看到了。”

敬老从心开始&#xff0c;助老从我做起 时值假期&#xff0c;我们有了时间&#xff0c;决定好好践行孝亲敬老的传统美德。会计学院红心使者敬老院访问团在7月6日上午在河南省郑州市新郑市“华信老年公寓”进行实践活动。 一早来到敬老院&#xff0c;老人们都已经开始择菜&…

某赛通电子文档安全管理系统 PolicyAjax SQL注入漏洞复现

0x01 产品简介 某赛通电子文档安全管理系统(简称:CDG)是一款电子文档安全加密软件,该系统利用驱动层透明加密技术,通过对电子文档的加密保护,防止内部员工泄密和外部人员非法窃取企业核心重要数据资产,对电子文档进行全生命周期防护,系统具有透明加密、主动加密、智能…

Redis核心技术与实战【学习笔记】 - 19.Pika:基于SSD实现大容量“Redis”

前言 随着业务数据的增加&#xff08;比如电商业务中&#xff0c;随着用户规模和商品数量的增加&#xff09;&#xff0c;就需要 Redis 能保存更多的数据。你可能会想到使用 Redis 切片集群&#xff0c;把数据分散保存到不同的实例上。但是这样做的话&#xff0c;如果要保存的…

【鸿蒙】大模型对话应用(三):跨Ability跳转页面

Demo介绍 本demo对接阿里云和百度的大模型API&#xff0c;实现一个简单的对话应用。 DecEco Studio版本&#xff1a;DevEco Studio 3.1.1 Release HarmonyOS SDK版本&#xff1a;API9 关键点&#xff1a;ArkTS、ArkUI、UIAbility、网络http请求、列表布局、层叠布局 页面跳…

excel统计分析——卡方适合性检验

参考资料&#xff1a;生物统计学 适合性检验是卡方检验应用的一种类型&#xff0c;检验实际的观测数与通过某一理论模型计算所得理论数是否相符&#xff0c;相当于1c列联表的卡方检验&#xff0c;也成为单因素离散型数据的卡方检验。 对参数的建设检验总是假定对照总体的分布数…

Linux 网络编程 + 笔记

协议&#xff1a;一组规则 分层模型结构&#xff1a; OSI七层模型&#xff1a;物理层、数据链路层、网络层、传输层、会话层、表示层、应用层TCP/IP 4层模型&#xff1a;链路层/网络接口层、网络层、传输层、应用层 应用层&#xff1a;http、ftp、nfs、ssh、telnet、传输层&am…

C++ 动态规划 线性DP 数字三角形

给定一个如下图所示的数字三角形&#xff0c;从顶部出发&#xff0c;在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点&#xff0c;一直走到底层&#xff0c;要求找出一条路径&#xff0c;使路径上的数字的和最大。 73 8 8 1 02 7 4 4 4 5 2 6 5 输入格式 …

Qt/C++音视频开发66-音频变速不变调/重采样/提高音量/变速变调/倍速播放/sonic库使用

一、前言 之前在做倍速这个功能的时候&#xff0c;发现快速播放会有滴滴滴的破音出现&#xff0c;正常1倍速没有这个问题&#xff0c;尽管这个破音间隔很短&#xff0c;要放大音量才能听到&#xff0c;但是总归是不完美的&#xff0c;后面发现&#xff0c;通过修改qaudiooutpu…

Postman-接口测试教程

接口是软件开发中常用的概念&#xff0c;是软件生产过程中比较核心的任务。对于接口开发者&#xff0c;调试接口是一件较为繁琐的事情&#xff0c;很多时候需要线上线下来回切换。在这里&#xff0c;我就跟大家介绍一个只需要在本地就可以调试接口的方法&#xff0c;即使用post…

node.js与express.js创建项目以及连接数据库

搭建项目 一、技术准备 node版本&#xff1a;16.16.0 二、安装node成功后&#xff0c;安装express,命令如下&#xff1a; npm install -g express 或者&#xff1a; npm install --locationglobal express 再安装express的命令工具&#xff1a; npm install --location…

嵌入式学习第三篇——51单片机

目录 1&#xff0c;嵌入式系统 1&#xff0c;嵌入式系统的定义 2&#xff0c;单片机的定义 2&#xff0c;51单片机 1&#xff0c;开发环境 2&#xff0c;开发板使用的基本思路 1&#xff0c;查看原理图&#xff0c;查看芯片手册 2&#xff0c;获得调用硬件的管…

AI的安全应答之道

作者&#xff1a;统信UOS技术团队 2023,随着各种大语言模型的爆发&#xff0c;整个AI生态正处于从决策式AI进化到生成式AI的进程中。各类AI模型和AI应用层出不穷&#xff0c;也随之带来了与AI相关的各类潜在风险。AI开发和使用过程中的风险防范和治理&#xff0c;成为了不可忽…

SD-WAN的安全性体现在哪里?

SD-WAN技术以其高度灵活、网络自动配置和低成本等优势&#xff0c;将多个物理WAN链接整合为一个逻辑网络&#xff0c;推动网络从“连通驱动”向“服务驱动”导向的转变。同时&#xff0c;企业在追求高效网络时&#xff0c;SD-WAN的安全性也成为一个重要的考量因素。 SD-WAN采用…

OpenCV 8 - 模糊处理(均值滤波,高斯滤波,中值滤波,双边滤波)

模糊处理原理: Blur是图像处理中最简单和常用的操作之一,使用该操作的原因为了给图像预处理时候减低噪声使用,Blur操作其背后是数学的卷积计算, 通常这些卷积算子计算都是线性操作,所以又出线性虑波。 假设有6x6的图像像素点矩阵。卷积过程:6x6上面是个3x3的窗口,从左向右,…

c语言面向过程编码方式

使用模块化编程的方式实现c语言面向过程编码&#xff1a;将main文件&#xff0c;Util文件&#xff0c;头文件分开进行处理 c语言程序头文件 c语言头文件代码 #ifndef __Object_H_ #define __Object_H_// 这个位置编写头文件的代码 int markStudentId(int year, int classNum, …

Hive 主要内容一览

Hive架构 用户接口&#xff1a;Client CLI&#xff08;command-line interface&#xff09;、JDBC/ODBC(jdbc访问hive) 元数据&#xff1a;Metastore 元数据包括&#xff1a;表名、表所属的数据库&#xff08;默认是default&#xff09;、表的拥有者、列/分区字段、表的类型&am…

Vim工具使用全攻略:从入门到精通

引言 在软件开发的世界里&#xff0c;Vim不仅仅是一个文本编辑器&#xff0c;它是一个让你的编程效率倍增的神器。然而&#xff0c;对于新手来说&#xff0c;Vim的学习曲线似乎有些陡峭。本文将手把手教你如何从Vim的新手逐渐变为高手&#xff0c;深入理解Vim的操作模式&#…

【测试运维】性能测试笔记文档第2篇:性能测试分类和指标(已分享,附代码)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论性能测试相关知识。入门阶段&#xff1a;认识性能测试分类-(负载测试、压力测试、并发测试、稳定性测试)&#xff0c;常用性能测试指标-(吞吐量、并发数、响应时间、点击数…)&#xff0c;性能测试工具选择。性能脚本&a…

如何在Vue应用程序中使用Vue-Router来实现路由嵌套动画效果

Vue-Router是Vue.js官方的路由管理插件&#xff0c;可以帮助我们轻松管理应用程序的路由。除了基本的路由功能外&#xff0c;Vue-Router还允许我们在切换路由时添加动画效果&#xff0c;提升用户体验。本文将介绍如何使用Vue-Router来实现路由嵌套动画效果&#xff0c;并提供具…