1003题目(双语)
【Problem Description 问题描述】
Given a sequence a[1], a[2], a[3]......a[n], your job is to calculate the max sum of a sub - sequence.For example, given(6, -1, 5, 4, -7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.
给定序列 a[1],a[2],a[3]......a[n],你的工作是计算子序列的最大和。例如,给定(6, -1, 5, 4, -7),此序列中的最大总和为6 + (-1) + 5 + 4 = 14。
【Input 输入】
The first line of the input contains an integer T(1 <= T <= 20) which means the number of test cases.Then T lines follow, each line starts with a number N(1 <= N <= 100000), then N integers followed(all the integers are between - 1000 and 1000).
输入的第一行包含一个整数 T(1 <= T <= 20),表示测试用例的数量。然后是 T 行,每行以一个数字 N(1 <= N <= 100000) 开头,然后是 N 个整数(所有整数都在 - 1000 和 1000 之间)。
【Output 输出】
For each test case, you should output two lines.The first line is "Case #:", # means the number of the test case.The second line contains three integers, the Max Sum in the sequence, the start position of the sub - sequence, the end position of the sub - sequence.If there are more than one result, output the first one.Output a blank line between two cases.
对于每个测试用例,您应该输出两行。第一行是 “Case #:”,# 表示测试用例的编号。第二行包含三个整数,序列中的 Max Sum、子序列的开始位置、子序列的结束位置。如果有多个结果,则输出第一个结果。在两个 case 之间输出一个空行。
【Sample Input 样本输入】
2
5 6 - 1 5 4 - 7
7 0 6 - 1 1 - 6 7 - 5
【Sample Output 示例输出】
Case 1:
14 1 4
Case 2 :
7 1 6
【解题思路】
1、先定义输入T,明确Case的数量;
2、设置T的大循环编写Case的处理;
3、在大循环里定义输入Case的数num的个数len;
4、设置len的小循环;
5、思考变量更新的逻辑。注意sum<0不着急马上把max值再初始化为0,因为再重新求和sum的值不是一定比之前的大;要在新的sum和max的比较确定后,才可以知道max是否要更新。子序列的开始位置L同理,(max有sum来保留记录,L也要),设置一个临时的L即tempL,以防更新。
5、设置每个Case(小循环)结束后的变量重置等;
6、检测小细节,如单词大小写、输出要换行/空行等;
【代码展示】
#include<iostream>
//#include<string>//输出法2才用
using namespace std;
signed main() {
int num;//每个case输入的数
int T;
cin >> T;
if (T < 0 || T>20) {
cout << "T的范围是1-20";
return 1;
}
for (int i = 1; i <= T; i++) {
//这些值是每个case不同的,要在大循环里更新
int L = 1, R = 1, tempL = 1;
int sum = 0, max = INT_MIN;//(INT_MIN 是一个宏定义,它表示整型变量可以表示的最小值。)初始化为 INT_MIN,确保它可以被任何实际的输入值更新。
//这样做可以确保即使输入全部为[负数],也能正确找到最大的子序列和。
int len = 0;//初始化case的长度/个数
cin >> len;
cout << "Case "<< i << ":" << endl;
//cout << "Case " + to_string(i) + ":" << endl;//(输出法2)C++不能拼接字符和非字符,要转换i
for (int j = 1; j <= len; j++) {
cin >> num;
sum += num;
if (sum > max) {//比较,sum更大就赋值给max
max = sum;
//R +=1;//不行的,子序不是简单的递增,是和序列号有关的
R = j;
L = tempL;
}
if (sum < 0) {
//L = j + 1;//"加上后sum<0,那后面再加也不会得到max,相当于开头就输了"错!后面的可能更小
tempL = j + 1;//先用个临时的,真的大再换!!!
sum = 0;//舍掉前面,从给下一个从新开始
//max = 0;//max是不用马上等于0的
}
}
cout << max << " " << L << " " << R << endl;
cout << endl;
}
return 0;
}
注意点:
1、循环的设置,包括变量值的更新;
2、INT_MIN的使用(这样做可以确保即使输入全部为[负数],也能正确找到最大的子序列和,0不行);
3、C++书写的规范性和语法特性。