H - 最大连续子序列
描述
给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ...,
Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个,
例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和
为20。
在今年的数据结构考卷中,要求编写程序得到最大和,现在增加一个要求,即还需要输出该
子序列的第一个和最后一个元素。
输入
测试输入包含若干测试用例,每个测试用例占2行,第1行给出正整数K( < 10000 ),第2行给出K个整数,中间用空格分隔。当K为0时,输入结束,该用例不被处理。
输出
对每个测试用例,在1行里输出最大和、最大连续子序列的第一个和最后一个元
素,中间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个(如输入样例的第2、3组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。
样例输入
-2 11 -4 13 -5 -2
10
-10 1 2 3 4 -5 -23 3 7 -21
6
5 -8 3 2 5 0
1
10
3
-1 -5 -2
3
-1 0 -2
0
样例输出
10 1 4
10 3 5
10 10 10
0 -1 -2
0 0 0
坑点:
如果数据是 4 0 1 1 1这个数据,输出的结果应该是3 0 1.
主要几个地方:
第一个:如果是加了之后的数为负数,那么他的寻找数的start和end,应该都变成下一个数,而不是这个数。
比如: number = 10,下一个为-11,那么他的number的start和end应该变成-11对应下标的下一个。而不是-11的下标。
第二个:保存输出的那个start和寻找的number的start之间的关系。
(第三个代码时间长了些,暂时还没有减少代码量。你们可以参照前面的两个代码,将第三个代码减少代码量。也可以不看第三个代码,毕竟第三个代码只是按照我的想法一步一步推过来的。以理解为主。)
先版署几个时间比较少的代码:
代码一:
#include <iostream> using namespace std; int chen[10005]; int main() { int m,n,i,j,k,sum,t,s1,s2,max,q1,q2; while(scanf("%d",&n)!=EOF) { memset(chen,0,sizeof(chen)); if(n==0) break; for(i=1;i<=n;i++) scanf("%d",&chen[i]); sum=0;max=-999199;k=1; q1=chen[1]; for(i=1;i<=n;i++) { sum+=chen[i]; if(sum>max) { max=sum; s1=k; q1=chen[s1]; s2=i; q2=chen[s2]; } if(sum<0) { sum=0; k=i+1; } } if(max<0) {max=0;q1=chen[1];q2=chen[n];} cout<<max<<' '<<q1<<' '<<q2<<endl; } return 0; }代码二:
#include<iostream> #include<cstdio> using namespace std; int main(){ int kase,k,i,c[10005],s,e,sum,maxv,n,t; while(scanf("%d",&n)==1&&n){ t=1,sum=0,maxv=-100000; for(i=1;i<=n;++i) scanf("%d",&c[i]); for(i=1;i<=n;++i){ if(c[i]>=0) break; } if(i>n) { printf("0 %d %d\n",c[1],c[n]); continue; } for(i=1;i<=n;i++){ if(sum>=0) sum+=c[i]; else if(sum<0){ t=i; sum=c[i]; } if(sum>maxv){ s=t; e=i; maxv=sum; } } printf("%d %d %d\n",maxv,c[s],c[e]); } return 0; }
再来一个较长时间的代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[10005]; int main() { int n; while(cin>>n,n) { memset(a,0,sizeof(a)); int te =0 ; for(int i=0; i<n; i++) { cin>>a[i]; if(a[i]<0) te++; } int max=0,min=0; int k=0,t=0; int k1=0,t1=0; if(te==n) min=0; else { for(int i = 0; i<n; i++) { if(i==0) { k1 = a[i]; t1 = a[i]; } max+=a[i]; t1 = a[i]; if(max>min) { min=max; k=k1; t=t1; } else if(max < 0) { max = 0; k1 = a[i+1]; t1 = a[i+1]; } } } if(min==0) { k = a[0]; t = a[n-1]; } if(min==0 && te!=n) { k=0; t=0; } cout<<min<<" "<<k<<" "<<t<<endl; } return 0; }