电脑坏了,忘了发了。。。。
题目:返回一个二维整数数组中最大子数组的和。
要求: 输入一个二维整形数组,数组里有正数也有负数。
二维数组首尾相接,象个一条首尾相接带子一样。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。
思路:
将求二维数组最大子数组与一维数组首尾相连求最大子数组结合起来
代码:
#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从头再开始计算