Task 4.5 求二维数组中的最大连通子数组之和

任务:输入一个二维整形数组,数组里有正数也有负数。 求所有子数组的和的最大值。要求时间复杂度为O(n)。

1.设计思想:因为用之前的解决子数组最大和的问题的思路一直没能解决这个问题,后来看到同学使用将矩阵转化为图的思路将结果得出了,所以我就沿着这个思路一步一步的分析了一下。开始先将将二维矩阵转换成图的存储形式,当两个相邻的数之间是联通的时,记长度为1,否则就是0;将整个图从每个点都开始遍历一遍,遍历过程中时,当和小于0时断开两点间的路,当和大于最大和时改变最大和的值,取以每个点为起点遍历的和的最大值即时最大联通子数组的和。遍历时,选取已遍历的联通子数组周围最大值遍历。经过重复的几次遍历就可以确定此数组中最大连通数组和了。

2.源代码:

#include<iostream>
#define N 100
#include<ctime>
using namespace std;

typedef struct
{
    int d[N];
    int a[N][N];
    int x;
}A;

void set(A &shu, int x, int y)//x,y分别是行数和列数
{
    shu.x = x*y;
    srand((unsigned)time(NULL));
    for (int i = 1; i <= shu.x; i++)
    {
        shu.d[i] = rand() % 10;
        if (rand() % 2 == 1)
            shu.d[i] = shu.d[i] * (-1);
    }//随机生成数组的数
    for (int i = 1; i <= shu.x; i += y)
    {
        for (int j = i; j <= i + y - 2; j++)
        {
            shu.a[j][j + 1] = 1;
            shu.a[j + 1][j] = 1;
        }
    }
    for (int i = 1 + y; i<shu.x; i += y)
    {
        for (int j = i; j <= i + x - 1; j++)
        {
            shu.a[j][j - y] = 1;
            shu.a[j - y][j] = 1;
        }
    }//将随机生成的一维数组转换成二维的图的形式
}
void output(A shu)
{
    for (int i = 1; i <= shu.x; i++)
    {
        cout  << shu.d[i] ;
        if (shu.a[i][i + 1] == 1)
            cout << "   ";
        else
            cout << endl;
    }
}
void bianli(A &shu, int v, int visit[], int &b, int &max, int x)
{
    visit[v] = 1;

    max += shu.d[v];
    if (max >= b)
        b = max;

    int a = 0, bo = 0;
    for (int w = 1; w <= shu.x; w++)
    {
        for (int c = 1; c <= shu.x; c++)
        {
            if ((visit[w] == 0) && (shu.a[c][w] == 1) && (visit[c] == 1))
            {
                a = w; bo = 1; break;
            }
        }
        if (bo == 1)
            break;
    }
    for (int w = 1; w <= shu.x; w++)
    {
        for (int c = 1; c <= shu.x; c++)
        {
            if ((visit[w] == 0) && (shu.a[c][w] == 1) && (visit[c] == 1))
            {
                if (shu.d[a]<shu.d[w])
                    a = w;

            }
        }
    }
    if (b + shu.d[a]<0)
    {
        shu.a[v][a] = 0;
    }
    else
        bianli(shu, a, visit, b, max, x);
}
//遍历

int NoVisit(int visit[], A shu)
{
    int k = 0, i;
    for (i = 1; i <= shu.x; i++)
    {
        if (visit[i] == 0)
        {
            k = i;
            break;
        }
    }
    return k;
}//判断图中没有visit的项

int main()
{
    cout << "请输入数组行数和列数:" << endl;
    int x, y;
    cin >> x >> y;
    A shu;
    set(shu, x, y);
    output(shu);

    int v = 1, b[N] = { 0 }, h = 0;

    for (int i = 1; i <= shu.x; i++)
    {
        if (shu.d[i]<0)
        {
            b[i] = shu.d[i];
        }
        else
        {
            int visit[N] = { 0 };
            int max = 0;
            bianli(shu, i, visit, b[i], max, x);
        }
    }

    int max = b[1];
    for (int i = 2; i <= shu.x; i++)
    {
        if (b[i]>max)
            max = b[i];
    }
    cout << "最大联通子数组的和为:" << max << endl;
}
时间: 2024-10-13 03:16:34

Task 4.5 求二维数组中的最大连通子数组之和的相关文章

求二维数组环的最大的子数组的和

#include<iostream> using namespace std; void max(int row,int col) { int ** a=new int*[row+1]; int ** b=new int*[row+1]; int h;//用于每一个一维数组上已经相加元素的个数够一个环则开始下一个 for(int i=1;i<=row;i++) { a[i]=new int[2*col]; } for(int i=1;i<=row;i++) { b[i]=new i

求二维数组中最大子数组的和

一.题目: 返回一个二维整数数组中最大子数组的和. 要求: 输入一个二维整形数组,数组里有正数也有负数. 二维数组中连续的一个子矩阵组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n). 二:结对编程要求: 两人结对完成编程任务. 一人主要负责程序分析,代码编程. 一人负责代码复审和代码测试计划. 发表一篇博客文章讲述两人合作中的过程.体会以及如何解决冲突(附结对开发的工作照). 三:设计思路: 将二维数组的每行轮番逐次相加(包括单行)后看成一维数组,利用求

软件工程结对开发之求二维数组中连续最大子数组之和2

一.题目要求 题目:返回一个二维整数数组中最大子数组的和. 要求: 输入一个二维整形数组,数组里有正数也有负数. 二维数组首尾相接,象个一条首尾相接带子一样. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n). 二.设计思路 先调用以前求二维最大连续子数组之和的maxSubArray函数求一个首尾不相邻的二维最大连续子数组之和,接着用将第k列各元素左移一列可以再求一个最大连续子数组之和 ,循环m次(因为原二维数组有m列)求得每个

二维数组成环最大和的子数组的和

设计思想:综合了前面一维数组成环和二维数组求最大子数组的思想. 屏幕截图: : 总结: 把做过的程序封装成一个个的接口,当使用时直接调用即可. 源代码: //jiangzhongxi 2015/4/16#include<iostream>using namespace std;void max(int row,int col){ int ** a=new int*[row+1];    int ** b=new int*[row+1];    int h;//用于每一个一维数组上已经相加元素的

求二维数组中子数组和中最大的值,及子数组

求二维数组中子数组和中最大的值,及子数组 个人信息:就读于燕大本科软件工程专业 目前大三; 本人博客:google搜索"cqs_2012"即可; 个人爱好:酷爱数据结构和算法,希望将来从事算法工作为人民作出自己的贡献; 编程语言:C++ ; 编程坏境:Windows 7 专业版 x64; 编程工具:vs2008; 制图工具:office 2010 powerpoint; 硬件信息:7G-3 笔记本; 真言 每次着急写程序,碰到问题就头疼,头疼之后便是满满的收获,付出总有回报. 题目 求

二维数组中最大子数组的和

题目:返回一个二维整数数组中最大子数组的和. 要求: 输入一个二维整形数组,数组里有正数也有负数. 二维数组中连续的一个子矩阵组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n). 思路: 借鉴网上代码整理得思路: 根据一位数组最大子数组求和的编程思路,讲二维数组转化成一维数组求解: 即求出每一行的最大子数组之和,通过比较各行最大子数组之和的大小,求出只有二维数组只有一行的情况下的最大子数组之和: 然后求每两行最大子数组之和,即将每两行的相同列相加,将二维数

求二维数组的最大子数组

一.题目: n返回一个二维整数数组中最大子数组的和. 二.要求: n输入一个二维整形数组,数组里有正数也有负数. n二维数组中连续的一个子矩阵组成一个子数组,每个子数组都有一个和. n求所有子数组的和的最大值.要求时间复杂度为O(n). 三.程序源码: import java.util.Random; import java.util.Scanner; public class dd { public static void main(String[] args) { // TODO Auto-

求二维数组的马鞍点-C程序设计-7.8习题

找出一个二维数组中的鞍点,即该位置上的元素在该行上最大,在该列最小.也可能没有鞍点. 下面是我做这道题时候的代码,如果有不正确的地方,还望大家多多指教. //马鞍点:矩阵中在行上最大,列上最小的点. #include <stdio.h> #define ROW 10 #define COLUMN 10 int i,j,m,n; int arr[ROW][COLUMN]; int main(){ void maandian(int arr[ROW][COLUMN]); printf("

3月31号周二课堂练习:结对开发----求二维数组组成的矩阵中子矩阵的最大值二

一.题目要求 1.1输入一个二维整形数组,数组里有正数也有负数. 1.2二维数组首尾相接,象个一条首尾相接带子一样. 1.3数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 1.4求所有子数组的和的最大值.要求时间复杂度为O(n). 二.结对要求 2.1两人结对完成编程任务. 2.2一人主要负责程序分析,代码编程. 2.3一人负责代码复审和代码测试计划. 2.4发表一篇博客文章讲述两人合作中的过程.体会以及如何解决冲突(附结对开发的工作照). 三.设计过程 上次已经算过二维数组中