zoukankan      html  css  js  c++  java
  • 二维数组首尾相连最大子数组

    电脑坏了,忘了发了。。。。

    题目:返回一个二维整数数组中最大子数组的和。

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

             二维数组首尾相接,象个一条首尾相接带子一样。

             数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。

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

    思路:

    将求二维数组最大子数组与一维数组首尾相连求最大子数组结合起来

    代码:

    #include <iostream>
    #include <cstring>  
    #include <assert.h>
    const int N = 500;
    const int INF = -9999;
    using namespace std;
    
    void output(int a[][N], int n, int head, int foot, int begin, int last)    //head、foot表示上下界限,begin、last表示左右界限
    {
        int i,j;
    
        cout<<"子数组为:"<<endl;
        for(i=head; i<=foot; i++)
        {
            if ( last < begin)
            {
                for (j=begin; j<n; j++)
                {
                    cout<<a[i][j]<<" ";
                }
                for (j=0; j<=last; j++)
                {
                    cout<<a[i][j]<<" ";
                }
                cout<<endl;
            }
            else
            {
                for (j=begin; j<=last; j++)
                {
                    cout<<a[i][j]<<" ";
                }
                cout<<endl;
            }
        }
    
        cout<<endl;
    }
    
    int maxSubArray(int a[], int n, int &begin, int &last)   
    {
        assert(a!=NULL && n>0);
    
        int max = INF;
        int sum;
    
        int i,j,k;
    
         for (i=0; i<n; i++)
         {
            sum = 0;
    
            for (j=i; j<n; j++)
            {
                sum += a[j];
                     
                if ( sum > max )
                {
                    max = sum;                    
                    begin = i;
                    last = j;
                }
            }
            for(k=0; k<i; k++)     //从首开始
            {
                sum += a[k];
    
                if ( sum > max )
                {
                   max = sum;
                   begin = i;
                   last = k;
                }
            }
         }
        
        return max;
    }
    
    int findMaxSubMatrix(int a[][N], int n) 
    {
        int tmpSum[N];
        int max = INF;
        int begin, last, begin1, last1, head, foot;
        
        //枚举所有行的可能组合
        for (int i=0; i<n; i++)
        {
            //将tmpSum清零
            memset(tmpSum, 0, sizeof(tmpSum));
            
            for (int j=i; j<n; j++)     
            {  
                //加上当前行的元素
                for(int k=0; k<n; k++)    //每一列
                {
                    tmpSum[k] += a[j][k];
                }
                int tmpMax = maxSubArray(tmpSum, n, begin1, last1);
                if(tmpMax >max) 
                {
                    begin = begin1;
                    last = last1;
                    head = i;
                    foot = j;
                    max=tmpMax;
                }
            }
    
        }
    
        output(a, n, head, foot, begin, last);
        
        return max;
    }
    
    int main()
    {
        int a[N][N];
        int n;    //数组的大小
        cout<<"请输入数组n*n中n的大小: "<<endl;
        while (cin>>n && n)
        {
            for (int i=0; i<n; i++)
            {
                for (int j=0; j<n; j++)
                {
                    int k=rand();
                    a[i][j]= k%2==0 ?rand()%100+1:(-rand()%100+1);
                }
            }
            for (int i=0; i<n; i++)
            {
                for (int j=0; j<n; j++)
                {
                    cout<<a[i][j]<<" ";
                }
                cout<<endl;
            }
    
            cout<<endl;
    
            cout<<"最大子数组的和为: "<<findMaxSubMatrix(a, n)<<endl;
        }
        
        return 0;
    }

    测试截图:

    1.n=4

    2.n=5

    感悟:

    程序还是有点麻烦,必须得定义一个k从头再开始计算

  • 相关阅读:
    AtCoder Beginner Contest 113 D Number of Amidakuji
    UVA
    mt19937 -- 高质量随机数
    牛客网NOIP赛前集训营-提高组(第七场)C 洞穴
    牛客OI周赛4-提高组 C 战争(war)
    牛客OI周赛4-提高组 B 最后的晚餐(dinner)
    bzoj 4318 || 洛谷P1654 OSU!
    Tourists Codeforces
    bzoj 1791 [Ioi2008]Island 岛屿
    洛谷 P2231 [HNOI2002]跳蚤
  • 原文地址:https://www.cnblogs.com/hongyedeboke/p/4457427.html
Copyright © 2011-2022 走看看