二维数组联通子数组和最大

思路:

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

题目要求:

放在一个input.txt的文件中

数组里面有正数有负数

返回联通子数组和最大的值

#include<fstream>
#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 &p, int x, int y)                 //x,y分别是行数和列数
{
    p.x = x*y;
    srand((unsigned)time(NULL));
    for (int i = 1; i <= p.x; i++)
    {
        p.d[i] = rand() % 10;
        if (rand() % 2 == 1)
            p.d[i] = p.d[i] * (-1);
    }                                        //随机生成数组的数
    for (int i = 1; i <= p.x; i += y)
    {
        for (int j = i; j <= i + y - 2; j++)
        {
            p.a[j][j + 1] = 1;
            p.a[j + 1][j] = 1;
        }
    }
    for (int i = 1 + y; i<p.x; i += y)
    {
        for (int j = i; j <= i + x - 1; j++)
        {
            p.a[j][j - y] = 1;
            p.a[j - y][j] = 1;
        }
    }                               //将随机生成的一维数组转换成二维的图的形式
}

void bianli(A &p, int v, int visit[], int &b, int &max, int x)
{
    visit[v] = 1;

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

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

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

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

int main()
{
    cout << "请输入数组行数和列数:" << endl;
    int x, y;
    cin >> x >> y;
    A p;
    set(p, x, y);
    ofstream fout("D:\\input.txt",ios::binary);
    for (int i = 1; i <= p.x; i++)
    {

        fout  << p.d[i] ;
        if (p.a[i][i + 1] == 1)
            fout << "   ";
        else
            fout << endl;
    }
    int v = 1, b[N] = { 0 }, h = 0;

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

    int max = b[1];
    for (int i = 2; i <= p.x; i++)
    {
        if (b[i]>max)
            max = b[i];
    }
  fout << "最大联通子数组的和为:" << max << endl;
}

时间: 2024-10-03 21:53:34

二维数组联通子数组和最大的相关文章

二维数组求子数组之和最大值(首尾相接, 圆柱)

问题:求二维数组的子数组之和的最大值(首尾相接,即形成圆柱) 成员: 陈晨:负责代码复审和代码测试计划 王颖瑞:负责程序分析,代码编程 思路:对于这个问题,我们可以结合之前的实验(二维数组求子数组之和的最大值和首尾相连一维数组的子数组之和的最大值),把为二维数组的列扩大二倍,之后想一维数组(首尾相连)一样,把二维数组分成不同的几个二维数组.之后就分开求不同的二维数组的子数组的最大值,最后之间比较,求出总的最大值. 代码: #include<iostream> using namespace s

二位数组的子数组最大值

该题是poj的1050号题:http://poj.org/problem?id=1050 同时在<编程之美> 2.15 小节 思想是: 1.把二维降到一维,把 同一列的若干个数的和算出来, 然后从行的角度,变成求一维数组的子数组和的最大值, 一共要计算 (1+n)*n/2 次一维数组的和最大值 2.在求同一列的若干数的和的时候,用辅助数组加快计算: 把第l列中, 第1~k行数的和提前计算好,放到辅助数组 b[k][l]中, 然后求 第l列的 第i行和第j行之间的数的和,就等于 b[i][l]-

求二维数组最大子数组合

#include<iostream> using namespace std; void main () {     int x,y,i,j,m=0,A[100][100];     cout<<"输入矩阵的行()和列";     cin>>x>>y;     if(x>100||y>100)     {         cout<<"请重新输入:";         cin>>x&

二维数组子数组的最大值之和

题目:求一个二维数组中其子数组之和的最大值. 人员: 陈晨:负责程序编写. 王颖瑞:负责代码复审和代码测试. 思路:对于求二维数组的子数组之和,思路和求一维数组的相差不多,但需要分析更多的情况,我跟舍友讨论之后,之后写的.以下是我的思路: 1.确定子数组的最大上界,从第一行依次向下,规定最大子数组的范围. 2.对于规定好的最大子数组的范围,把最大子数组按照一列有几个数,分成几种不同的行.(如第一组只有一行,第二组有两行等,列数和数组的列数相同) 3.对于第二步产生的几个数组,进行一维数组求子数组

软件工程个人作业05(二维数组求最大子数组的和)

题目:返回一个二维整数数组中最大联通子数组的和. 要求:输入一个二维整形数组,数组里有正数也有负数.求所有子数组的和的最大值.要求时间复杂度为O(n). 程序要使用的数组放在一个叫 input.txt 的文件中, 文件格式是: 数组的行数, 数组的列数, 每一行的元素, (用逗号分开) 每一个数字都是有符号32位整数,当然,行数和列数都是正整数.程序设计思路:此次试验考虑到需要求最大联通子数组和.可以定义一个类(其中有value,x,y,neighbor,select),主函数里定义一个二维的对

二维数组首尾相连

一.设计思路:通过综合求二维数组的最大子数组.求首尾相连的一维数组的最大子数组的算法,得出如下思路:首先将二维数组的子数组上下相加转化成许多一维数组,然后按照求首尾相连的一维数组的算法,遍历一维数组的所有子数组,求出子数组的最大值,即为首尾相连二维数组的子数组的最大值,并且在遍历过程中保留取得最大值的位置,输出二维数组的最大子矩阵. 二.代码 import java.awt.Point; import java.util.Scanner; public class main { public s

首尾相连的二维数组的最大子数组

一.设计思路:通过综合求二维数组的最大子数组.求首尾相连的一维数组的最大子数组的算法,得出如下思路:首先将二维数组的子数组上下相加转化成许多一维数组,然后按照求首尾相连的一维数组的算法,遍历一维数组的所有子数组,求出子数组的最大值,即为首尾相连二维数组的子数组的最大值,并且在遍历过程中保留取得最大值的位置,输出二维数组的最大子矩阵. 二.代码: import java.awt.Point; import java.util.Scanner; public class main { public

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

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

返回一个二维数组最大联通子数组的和

一.题目 输入一个二维整形数组,数组里有正数也有负数. 求所有子数组的和的最大值. 二.设计思想 方法一:首先若要对二维数组进行分析,之前我们已经做过关于一位数组的练习,所以我们可以把它化简成为一个一维数组.再先求每个一维数组的最大子数组和,并记下每行最大一维子数组的下标.这是就会分两种情况:第一种是行之间的最大子数组是相连的,这时就可以直接相加得到:第二种是不相连的,,这时候就把每行的最大子数组看成一个整体,再使每个最大数组块进行相连,求使其相连的最小代价.最后得到的结果就是最大联通子数组的和