思路:首先要把n行m列的二维数组压缩成m个一维数组,然后按照一维循环数组求最大子数组的方法求最大子矩阵。
先从第一行到第n行压缩n行的求出最大子矩阵,再从第2行到第n行压缩n-1行,再从第3行到第n行压缩n-2行.。。。以此类推。
需要注意的是正向压缩完毕后也要反向压缩,即从第n行到第1行压缩n行求出最大子矩阵,再从第n-1行到第1行压缩n-1行求出最大子矩阵,再从第n-2行到第1行压缩n-2行求出最大子矩阵.。。以此类推
然后比较所有求得的子矩阵,找出其中最大的那一个,即为二维循环数组的最大子矩阵
时间进度:因为有了返回一维循环数组中最大子数组和的基础所以写返回一个二维循环数组中最大子矩阵的和就比较轻松,累计用时1个半小时
代码如下
#include <iostream> #include <ctime> #define N 5 #define M 10 using namespace std; int maxxunhuan(int array[2*M] , int n){ int i,j,m = 0,c = 0; int sum = array[0],b= 0,max = 0; for(j = 0;j < n;j++) array[n+j] = array[j]; for(j = 0;j < n;j++){ b = 0; sum = 0; for(i = j;i < 2*n;i++){ if(b > 0) b += array[i]; else{ b = array[i]; c = i; } if(b > sum ){ m = i; if(m > c+n-1) break; else sum = b; } } if(sum > max) max = sum; } return max; } void twodimensionxunhuan(int array[N][2*M] , int n , int m){ int arr[100] ; int i,j,sum = 0,sum1 = 0,p,max = 0 ; for(p = 0;p < n;p++){ //正向求最大子矩阵 for(i = 0;i < m;i++) arr[i] = 0; for(i = 0;i < m;i++){ for(j = p;j < n;j++) arr[i] += array[j][i]; } sum = maxxunhuan(arr , m); if(sum > max) max = sum; cout<<' '<<"第"<<p+1<<"行到最后一行的最大循环子矩阵为: "<<sum<<endl; } cout<<' '<<"*********************************************** "<<endl; for(p = n-1;p >=0;p--){ //逆向求最大子矩阵 for(i = 0;i < m;i++) arr[i] = 0; for(i = 0;i < m;i++){ for(j = p;j >= 0;j--) arr[i] += array[j][i]; } sum1 = maxxunhuan(arr , m); if(sum1 > max) max = sum1; cout<<' '<<"第"<<p+1<<"行到第一行的最大循环子矩阵为: "<<sum1<<endl; } cout<<' '<<"*********************************************** "<<endl; cout<<' '<<"因此二维数组最大循环子矩阵为: "<<max<<endl; } int main(){ int array[N][2*M]; int i,j; memset(array,0,sizeof(array)); //初始化一维数组 cout<<"随机生成的一维数组为的:"<<endl; srand((unsigned)time(0)); for(i = 0;i < N;i++){ for(j = 0;j < M;j++){ array[i][j] = rand()%25-10; cout<<array[i][j]<<' '; } cout<<endl; } twodimensionxunhuan(array , N , M); return 0; }