mooc浙大数据结构PTA习题之最大子列和问题2(在线处理)

01-复杂度2 Maximum Subsequence Sum(25 分)

Given a sequence of K integers { N1N2, ..., NK }. A continuous subsequence is defined to be { NiNi+1, ..., Nj } where 1ijK. 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 Knumbers, 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

参考代码:(以下代码没拿满分,在“并列和对应相同i但是不同j,即尾是0”测试中显示错误。)

#include<iostream>  
using namespace std;  
int *getmaxsum(int a[], int n, int m[]){  
    int thissum=0, maxsum=0;//当我把对数组m的初始化工作,即m[0]={0};放到被调函数中时会出现如图所示的问题,编译时没问题,输入数值执行计算后跳出该窗口。  
    int i,num=0;  
    int flag = 0;//用于处理只有负数和零的子列,此时应输出0 0 0,用flag标记子列中是否出现了0。  
    thissum = 0; maxsum = 0;  
  
    for (i = 0; i < n; i++)  
    {  
        thissum += a[i];  
        if (a[i] == 0)  
        {  
            flag = 1;  
        }  
        if (thissum > maxsum)  
        {  
              
            maxsum = thissum;  
            m[2] = a[i];  
            num += 1;  
            if (num == 1)  
                m[1] = a[i];  
        }  
        else if (thissum < 0)  
        {  
            thissum = 0;  
            num = 0;  
        }  
    }  
    m[0] = maxsum;  
      
    if (maxsum == 0 && flag == 1)//处理只有负数和0的情况  
    {  
        m[0] = 0;  
        m[1] = 0;  
        m[2] = 0;  
    }  
    if (maxsum == 0 && flag == 0)//处理只有负数的情况  
    {  
        m[0]=0;m[1]=  a[0]; m[2] = a[n - 1];  
    }  
      
    return m;  
}  
int main()  
{  
    int k;  
    int m[3] = { 0};  
    cin >> k;  
    int *a = new int[k];  
    for (int i = 0; i < k; i++)  
        cin >> a[i];  
    int *b = getmaxsum(a, k,m);  
    for (int r = 0; r < 3; r++)  
    {  
        if (r == 2)  
            cout << b[2];  
        else  
            cout << b[r] << " ";  
    }  
  
    delete[]a;  
      
    return 0;  
}  

当我把对数组m的初始化工作放到被调函数中时会出现如下问题:


以下是同方法的满分代码,从mooc评论区复制并更改的,主要是更改了数组a的定义方式,由固定长度a[100]改成了如下方式,通过了“最大N”的测试,但我实在看不到我的和这段代码的区别。

#include<iostream>  
  
int Maxseq(int a[], int K);  
using namespace std;  
  
int  main()  
{  
    int K;  
      
    int Max;  
    //cout<<"请输入序列长度"<<endl;  
    cin >> K;  
    int *a = new int[K];  
    for (int i = 0; i<K; i++)  
        cin >> a[i];  
    Max = Maxseq(a, K);  
    delete[]a;  
    return 0;  
  
}  
int Maxseq(int a[], int K)  
{  
    int ThisSum = 0, MaxSum = 0;  
    int start = 0, end = 0;  
    int count = 0;  
    int flag = 0;  
    int first = 0, last = 0;  
    for (int i = 0; i<K; i++)  
    {  
  
        ThisSum += a[i];  
        if (a[i] == 0)  
            flag = 1;  
        ++count;  
        if (ThisSum>MaxSum)  
        {  
            MaxSum = ThisSum;  
            end = i;  
            start = end - count + 1;  
  
        }  
  
        else if (ThisSum<0)  
        {  
            ThisSum = 0;  
            count = 0;  
        }  
    }  
    first = a[start];  
    last = a[end];  
    if (MaxSum == 0 && flag == 1)  
    {  
        first = 0;  
        last = 0;  
    }  
    if (MaxSum == 0 && flag == 0)  
    {  
        first = a[0];  
        last = a[K - 1];  
    }  
    cout << MaxSum << " " << first << " " << last << endl;  
  
    return MaxSum;  
}  

更新:呃呃,附上对比满分代码之后的修改版,改了之后也是满分了,修改了记录子列最左的记录方式。我不知道什么数据能使两段代码输出的结果会不一样。

微笑

#include<iostream>  
using namespace std;
int *getmaxsum(int a[], int n, int m[]) {
	int thissum = 0, maxsum = 0;//当我把对数组m的初始化工作,即m[0]={0};放到被调函数中时会出现如吐所示的问题,编译时没问题,输入数值执行计算后跳出该窗口。  
	int i, num = 0;
	int flag = 0;//用于处理只有负数和零的子列,此时应输出0 0 0,用flag标记子列中是否出现了0。  
	thissum = 0; maxsum = 0;

	for (i = 0; i < n; i++)
	{
		thissum += a[i];
		if (a[i] == 0)
		{
			flag = 1;
		}
		++num;
		if (thissum > maxsum)
		{

			maxsum = thissum;
			m[2] = a[i];
			
			
			m[1] = a[i - num + 1];
		}
		else if (thissum < 0)
		{
			thissum = 0;
			num = 0;
		}
	}
	m[0] = maxsum;

	if (maxsum == 0 && flag == 1)//处理只有负数和0的情况  
	{
		m[0] = 0;
		m[1] = 0;
		m[2] = 0;
	}
	if (maxsum == 0 && flag == 0)//处理只有负数的情况  
	{
		m[0] = 0; m[1] = a[0]; m[2] = a[n - 1];
	}

	return m;
}
int main()
{
	int k;
	int m[3] = { 0 };
	cin >> k;
	int *a = new int[k];
	for (int i = 0; i < k; i++)
		cin >> a[i];
	int *b = getmaxsum(a, k, m);
	for (int r = 0; r < 3; r++)
	{
		if (r == 2)
			cout << b[2];
		else
			cout << b[r] << " ";
	}

	delete[]a;

	return 0;
}

更新:

我知道了,错误不是尾是0的状况,是开头是0的状况。

输入0  1  2  3  5  0  -7

我的代码输出6  1  3

满分代码输出6  0  3

按照题目要求,最大和相同时输出i,j最小的那一组,应该输出6 0 3。我的记录方式使子列首项不会是0。

猜你喜欢

转载自blog.csdn.net/wss123wsj/article/details/79768648
今日推荐