本实验取材于PTA
拿到此题目时,需要大家做到心里不要着急,毕竟这是一道英文题,
仔细回想,解决一道题目的核心在哪里,肯定或者必然是,输入数据,处理数据和输出数据,首先输入数据要做到给定一个N,输入N个数字
然后输出时,如果子列和为0。那就输出0并且输出首元素和尾元素,因此
#include<stdio.h>
#include<stdlib.h>
int main()
{
//输入
int num = 0;
int templeft = 0;
scanf("%d",&num);
int *arr = (int *)calloc(num,sizeof(int));
for(int i=0;i<num;i++)
{
scanf("%d",&arr[i]);
}
//处理
int maxs = -1;//点睛之笔 如果-1就不玩了
int thiss = 0;
int leftindex = 0;
int rightindex = num-1;
for(int i=0;i<num;i++)
{
thiss += arr[i];
if(thiss > maxs)
{
maxs = thiss;
leftindex = templeft;
rightindex = i;
}else if(thiss < 0)
{
thiss = 0;
templeft = i+1;
}
}
if(maxs<0)
printf("0 %d %d",arr[0],arr[num-1]);
else
printf("%d %d %d",maxs,arr[leftindex],arr[rightindex]);
return 0;
}
因此代码的核心,肯定在于这个处理这部分
int maxs = -1;//点睛之笔 如果-1就不玩了
int thiss = 0;
int leftindex = 0;
int rightindex = num-1;
for(int i=0;i<num;i++)
{
thiss += arr[i];
if(thiss > maxs)
{
maxs = thiss;
leftindex = templeft;
rightindex = i;
}else if(thiss < 0)
{
thiss = 0;
templeft = i+1;
}
}
也就是这段代码,为什么是核心,首先将左右索引,记录初值,然后像更新最大子列和一样,更新leftindex,而rightindex就是根据i变而变,毕竟是右端嘛!然后,再次回想题目,最大子列和的解决核心在于,
- 遇到子列和<0就丢弃
- 遇到比max大的值就是赋值
- 根据i的变化来不断变化
最后在这个三个方面解决问题,在遇到子列和<0的时候更新leftindex的值这里是templeft,遇到>maxs的时候,最左端leftindex就可以确定打小了,就是templeft,然后根据是否找到做最后的输出,可谓是点睛!
if(maxs<0)
printf("0 %d %d",arr[0],arr[num-1]);
else
printf("%d %d %d",maxs,arr[leftindex],arr[rightindex]);
return 0;