例13        最大子段和

题目描述

给出一段序列,选出其中连续且非空的一段使得这段和最大。例如在序列2,-4,3,-1,2,-4,3中,最大的子段和为4,该子段为3,-1,2。

输入格式

第一行是一个正整数N,表示了序列的长度。

第二行包含N个绝对值不大于10000的整数Ai ,描述了这段序列。

输出格式

一个整数,为最大的子段和是多少。子段的最小长度为1。

输入样例

7

2 -4 3 -1 2 -4 3

输出样例

4

(1)编程思路。

可以从长度为n的数列的最左端(设为数组元素a[1])开始扫描,一直到最右端(设为数组元素a[n-1])为止,记下所遇到的最大总和的子序列。

程序中定义变量maxsum保存最大连续子段和,cursum保存当前连续子段和。

初始时,cursum=a[0]、maxsum=a[0]。用循环for (i=1;i

在这一扫描过程中,从左到右记录当前子序列的和(即cursum= cursum+a[i]),若这个和不断增加(即当前a[i]为正,从而使cursum+a[i]>maxsum成为可能),那么最大子序列的和maxsum也增加,从而更新maxsum。如果往右扫描中遇到负数,那么当前子序列的和cursum会减小,此时cursum将会小于maxsum,maxsum也就不更新;如果扫描到a[i]时,cursum降到0时,说明前面已经扫描的那一段就可以抛弃了,这时需要将cursum置为0。这样,cursum将从i之后的子段进行分析,若有比当前maxsum大的子段,需要更新maxsum。这样一趟扫描结束后,就可以得到正确结果。

(2)源程序。

#include

int main()

{

int a[200001];

int n,i,maxsum,cursum;

scanf("%d",&n);

for (i=0;i

scanf("%d",&a[i]);

cursum=a[0];

maxsum=a[0];

for (i=1;i

{

if (cursum+a[i]>maxsum)

{

maxsum=cursum+a[i];

}

if (cursum+a[i]<0)

{

cursum=0;

}

else

cursum= cursum+a[i] ;

}

printf("%d\n",maxsum);

return 0;

}

习题13

13-1  最大差值

本题选自洛谷题库 (https://www.luogu.org/problem/P5146)

题目描述

HKE最近热衷于研究序列,有一次他发现了一个有趣的问题:

对于一个序列A1 ,A2 ⋯An ,找出两个数i,j,1≤i

现在给出这个序列,请找出Aj −Ai 的最大值。

输入格式

第一行为一个正整数n。

接下来n个整数,第k+1个整数为Ak 。

输出格式

一行为 (Aj −Ai )的最大值

输入样例

10

1 3 4 6 7 9 10 1 2 9

输出样例

9

(1)编程思路。

由于求Aj −Ai 的最大值的要求是下标j>i,也就是说最大的数是在最小的数后面才符合要求,因此不能简单地求序列的一个最大数max和一个最小数min(无法保证max一定在min的后面),然后输出max-min作为答案。

定义变量minnum保存序列的最小数,maxdiff保存最大差值,由于输入n>=2,因此可以先输入序列前两个数a和b,赋minnum的初值为a与b中的较小数,maxdiff的初值为b-a。

然后用循环for (i=3;i<=n;i++)对序列中的每一个元素Ai进行扫描处理。处理时,若当前Ai与最小数minnum的差值大于maxdiff,则更新maxdiff,这个更新一定是有效的,因为保存的最小数minnum一定在当前数Ai之前;若当前数Ai比最小数小,则更新最小数minnum为当前数Ai。

这样一趟扫描结束后,就可以得到正确结果。

(2)源程序。

#include

int main()

{

int minnum,maxdiff;

int i,n,a,b;

scanf("%d",&n);

scanf("%d%d",&a,&b);

minnum=a

maxdiff=b-a;

for (i=3;i<=n;i++)

{

scanf("%d",&a);

if (a

if (a-minnum>maxdiff) maxdiff=a-minnum;

}

printf("%d\n",maxdiff);

return 0;

}

13-2  连续自然数和

题目描述

对一个给定的自然数M,求出所有的连续的自然数段,这些连续的自然数段中的全部数之和为M。

例子:1998+1999+2000+2001+2002 = 10000,所以从1998到2002的一个自然数段为M=10000的一个解。

输入格式

包含一个整数的单独一行给出M的值(10≤M≤2,000,000)。

输出格式

每行两个自然数,给出一个满足条件的连续自然数段中的第一个数和最后一个数,两数之间用一个空格隔开,所有输出行的第一个按从小到大的升序排列,对于给定的输入数据,保证至少有一个解。

输入样例

10000

输出样例

18 142

297 328

388 412

1998 2002

(1)编程思路。

定义两个变量left和right用于指示待求子序列的最左端和最右端,初始时令left=1,right=(int)sqrt(2.0*n),显然此时1+2+…+right的和值sum(sum=(right-left+1)*(left+right)/2)会非常接近n。之后进行如下操作过程:

1)比较sum与n,根据sum与n的大小关系进行不同处理。简单描述就是若sum值大了,去掉子序列最左端的数,从而减少sum值;若sum值小了,将最右端数的下一个数加入子序列,从而增大sum值;若sum与n相等,则找到一个子序列的和等于n,输出此时子序列的left和right值,输出后和值sum中去掉子序列最左端的数以便继续向后找到其他的子序列。

2)重复上面的过程,直到left==right,此时子序列中只有一个数,搜索结束,退出。

(2)源程序。

#include

#include

int main()

{

int left,right,sum,n;

scanf("%d",&n);

left=1;   right=(int)sqrt(2.0*n);

sum=(right-left+1)*(left+right)/2;

while (left

{

if (sum==n)

{

printf("%d %d\n",left,right);

sum-=left++;

}

else if (sum

{

right++;

sum+=right;

}

else

{

sum-=left;

left++;

}

}

return 0;

}

13-3  Subsequence

本题选自北大POJ 题库(http://poj.org/problem?id=3061)。

Description

A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 10000, and a positive integer S (S < 100 000 000) are given. Write a program to find the minimal length of the subsequence of consecutive elements of the sequence, the sum of which is greater than or equal to S.

Input

The first line is the number of test cases. For each test case the program has to read the numbers N and S, separated by an interval, from the first line. The numbers of the sequence are given in the second line of the test case, separated by intervals. The input will finish with the end of file.

Output

For each the case the program has to print the result on separate line of the output file.if no answer, print 0.

Sample Input

2

10 15

5 1 3 5 10 7 4 9 2 8

5 11

1 2 3 4 5

Sample Output

2

3

(1)编程思路。

本题题意是:输入整数N和S,N表示数列中元素的个数,S表示一个和值,然后输入数列中的N个元素,求一个子序列长度最短的连续子序列,使子序列中全部元素的和大于等于S。输出这个子序列的长度。

用两个变量i和j表示子序列的两个端点,初始时i和j的值均为0,和值sum=0。

这个搜索过程简单描述为:先让右端点移动,并将右端点的值累加到和值sum中(语句为sum+=a[j++]),直到sum大于等于S,按要求更新答案;然后再让左端点移动,并将左端点的值从和值sum中减掉(语句为sum-=a[i++];),也随之更新答案,直到出现sum小于S后,右端点再移动。重复这个过程,直到右端点越过了原序列的最后一个数据。

(2)源程序。

#include

int main()

{

int t,i,j,a[100001],n,s,sum,minx;

scanf("%d",&t);

while(t--)

{

scanf("%d%d",&n,&s);

for(i=0;i

scanf("%d",&a[i]);

i=0;

minx=0x7fffffff;

sum=0;

for (j=0;j

{

while(sum

sum+=a[j++];

while(sum>=s)

{

if (minx>j-i) minx=j-i;

sum-=a[i++];

}

}

if (minx==0x7fffffff)

minx=0;

printf("%d\n",minx);

}

return 0;

}

c语言 最大子段和,C语言程序设计100例之(13):最大子段和相关推荐

  1. c语言经典程序表白6,经典C语言程序设计100例(6)

    [程序61] 题目:打印出杨辉三角形(要求打印出10行如下图) 1.程序分析: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 2.程序源代码: main() ...

  2. Go语言开发小技巧易错点100例(七)

    往期回顾: Go语言开发小技巧&易错点100例(一) Go语言开发小技巧&易错点100例(二) Go语言开发小技巧&易错点100例(三) Go语言开发小技巧&易错点10 ...

  3. c语言黑匡程序,2020年新版C语言实用程序设计100例流程图.docx

    C 语言实用程序 100 例 第一篇 基础与提高 实例 1 利用库函数编写基本显示程序 实例 2 变量属性 实例 3 运算符与类型 实例 4 关于程序结构 实例 5 显示函数曲线图 实例 6 二分法选 ...

  4. 黑马程序员——经典C语言程序设计100例

    1.数字排列 2.奖金分配问题 3.已知条件求解整数 4.输入日期判断第几天 5.输入整数进行排序 6.用*号显示字母C的图案 7.显示特殊图案 8.打印九九口诀 9.输出国际象棋棋盘 10.打印楼梯 ...

  5. 随机数插入排序c 语言,C语言程序设计100例之(22):插入排序

    例22  插入排序 问题描述php 排序是计算机程序设计中的一种重要操做,它的功能是将一个数据元素或记录的任意序列,从新排列成一个以关键字递增(或递减)排列的有序序列.算法 排序的方法有不少,简单插入 ...

  6. c语言编程 生理周期的程序,C语言程序设计100例之(9):生理周期

    例9    生理周期 问题描述 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为 23 天.28 天和33 天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如 ...

  7. 回旋矩形C语言,C语言程序设计100例之(27):回旋方阵

    例27        回旋方阵 问题描述 编写程序,生成从内到外是连续的自然数排列的回旋方阵.例如,当n=3和n=4时的回旋方阵如下图1所示. 图1  由内到外回旋方阵 输入格式 一个正整数n(1≤n ...

  8. 4位数的水仙花c语言,C语言程序设计100例之(4):水仙花数

    例4    水仙花数 题目描述 一个三位整数(100-999),若各位数的立方和等于该数自身,则称其为"水仙花数"(如:153=13+53+33),找出所有的这种数. 输入格式 没 ...

  9. 二级c语言编程案例,2011年计算机二级考试C语言经典程序设计100例(7)

    [程序31] 题目:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续 判断第二个字母. 1.程序分析:用情况语句比较好,如果第一个字母一样,则判断用情况语句或if语句判断第二个字 ...

  10. c语言程序设计植树,C语言程序设计100例之(19):欢乐的跳

    例19   欢乐的跳 题目描述 一个n个元素的整数数组,如果数组两个连续元素之间差的绝对值包括了[1,n-1]之间的所有整数,则称之符合"欢乐的跳",如数组1 4 2 3符合&qu ...

最新文章

  1. python基础===两个list之间移动元素
  2. 如何证明你的性能测试结果可信?
  3. python的特点和优点-【Python面试】 Python 的特点和优点是什么?
  4. linux 在某个core上的中断 affinity c语言函数,Linux中断处理体系结构
  5. Linux 文件查找(find)
  6. 根据时间戳生成编号_分布式系统的唯一ID生成算法对比
  7. php批量采集电视剧,如何通过PHP多线程批量采集下载远程网站图片代码实例
  8. sqlserver修改字段长度语句_SQL Server读懂语句运行 (三) SET STATISTICS PROFILE ON
  9. LeetCode 72 编辑距离
  10. JAVA中的按值传递
  11. 物理内存管理之zone详解
  12. (45.2)【端口漏洞发现】扫描工具Nmap、Nessus、Masscan、端口弱口令检查
  13. vs2010英文版变中文版
  14. 云知声终止IPO:持续亏损7.9亿、毛利率低于行业均值、市场份额被指“造假”
  15. CF 815C 树形背包
  16. 12306 验证码识别源码
  17. Avoiding 16 Common OpenGL Pitfalls(避免 16 个常见的 OpenGL 陷阱)
  18. 《ChatGPT》自动写代码、写作文,使用教程来了
  19. 如何在线免费PDF转换PPT
  20. EXCEL中日期的加减函数

热门文章

  1. 推荐一款基于bootstrap的漂亮的前端模板——inspinia_admin
  2. 串口-TCP调试助手
  3. 关于tcp/udp网络调试助手错误提示
  4. selenium 在pycharm中安装selenium
  5. 数据包络分析法(DEA)_2
  6. 数据包络分析--综合的双目标数据包络分析模型
  7. 方方格子access_安装了这两款Office插件,我确信你的办公效率会大大提高!
  8. 自然语言处理发展的四大阶段
  9. 动态壁纸安卓_高清无水印!这4款壁纸软件,让你的手机好看又独特
  10. MAC IDEA常用快捷键