zoukankan      html  css  js  c++  java
  • 返回二维数组最大联通子数组的和

    一.题目

        输入一个二维整形数组,数组里有正数也有负数。

    求所有子数组的和的最大值。

    二.设计思想

       第一种方法:首先若要对二维数组进行分析,通常想要把它化简成为一个一维数组。再先求每个一维数组的最大子数组和,并记下每行最大一维子数组的下标。这是就会分两种情况:第一种是行之间的最大子数组是相连的,这时就可以直接相加得到;第二种是不相连的,,这时候就把每行的最大子数组看成一个整体,再使每个最大数组块进行相连,求使其相连的最小代价。最后得到的就是最大联通子数组的和。

       第二种方法:在二维整形数组中,数据可能会有正也有负,要求最大值,我们重点关注正数,所以要首先判断二维数组中哪些位置上的数是正数,利用另一个二维数组记录正数的位置,然后判断哪些数是连通的。首先定位这个二维数组中的最大值,然后在分析这个值周围的4个数,联通这4个数中的正数,若全为负数,则查找次大值,并与最大值联通,判断联通前与联通后值得大小,若变小则不联通最大值,若变大则联通最大值,以此类推,直到最大联通子数组怎么联通都比原来的值小。

    三.实验代码

    #include<iostream>
    #include<fstream>
    using namespace std;
    # define N 100
    int zuida(int n, int a[], int *p, int *q)//一维数组的最大子数组和
    {
    	int b[N] = { 0 };
    	int i, sum1 = 0, max1 = 0;
    	for (i = 0; i<n; i++)
    	{
    		if (sum1<0)
    		{
    			sum1 = a[i];
    		}
    		else
    		{
    			sum1 = sum1 + a[i];
    		}
    		b[i] = sum1;
    	}
    	max1 = b[0];
    	for (i = 0; i<n; i++)
    	{
    		if (max1<b[i])
    		{
    			max1 = b[i];
    			*q = i;  //记录最大子数组的终点位置
    		}
    	}
    	for (i = *q; i >= 0; i--)
    	{
    		if (b[i] == a[i])
    		{
    			*p = i;//记录最大子数组的起点
    			break;
    		}
    	}
    	return max1;
    }
    int main()
    {
    	int m1, m2, i, j, p, q, t2;
    	int sum, max;
    	int left[N], right[N], t[N];
    	int a[N][N], b[N];
    	ifstream fin("sz.txt");
    	ifstream fin1("sz1.txt");
    	fin1 >> m1 >> m2;
    	cout << "二维数组的行和列为"<< endl;
    	cout << m1 << "  " << m2 << endl;
    	for (int i = 0; i < m1; i++)
    	for (int j = 0; j < m2; j++)
    	{
    		fin >> a[i][j];
    	}
    	cout << "TXT文件中的二维数组为" << endl;
    	for (int i = 0; i < m1; i++)
    	{
    		for (int j = 0; j < m2; j++)
    		{
    			cout << a[i][j] << " ";
    		}
    		cout << endl;
    	}
    	for (i = 0; i<m1; i++)//求每一行最大子数组
    	{
    		for (j = 0; j<m2; j++)
    		{
    			b[j] = a[i][j];
    		}
    		sum = zuida(m1, b, &p, &q);
    		left[i] = p;     //记录最大子数组的坐标位置
    		right[i] = q;
    		t[i] = sum;
    
    	}
    	t2 = t[0];
    	for (i = 0; i + 1<m2; i++)//将最大子数组合并
    	{
    		if (left[i] <= right[i + 1] && right[i] >= left[i + 1])//两行的最大子数组块相连
    		{
    			t2 += t[i + 1];
    		}
    		for (j = left[i]; j<left[i + 1]; j++)
    		{
    			if (a[i + 1][j]>0)
    				t2 += a[i + 1][j];                   //判别独立正数
    		}
    
    	}
    	cout <<"最大子数组和为:"<< t2 << endl;
    	return 0;
    }
    

     实验总结:

    通过这次试验,我们考虑到了更多的细节问题,由一维数组转换到二维数组,需要更多的考虑。

  • 相关阅读:
    007_在线解析json工具
    009_python魔法函数
    008_python列表的传值与传址
    008_python内置语法
    007_Python中的__init__,__call__,__new__
    006_Python 异常处理
    匹配网络设计
    Bessel函数
    system generator 卷积编码器快速设计
    关于非稳恒的电流激励电场
  • 原文地址:https://www.cnblogs.com/zjj123456/p/5360266.html
Copyright © 2011-2022 走看看