九度OJ 1139:最大子矩阵 (矩阵运算、缓存)

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:1014

解决:376

题目描述:

已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵。
比如,如下4 * 4的矩阵

0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2

的最大子矩阵是

9 2
-4 1
-1 8

这个子矩阵的大小是15。

输入:

输入是一个N * N的矩阵。输入的第一行给出N (0 < N <= 100)。
再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给出第二行的N个整数……)给出矩阵中的N2个整数,整数之间由空白字符分隔(空格或者空行)。
已知矩阵中整数的范围都在[-127, 127]。

输出:

测试数据可能有多组,对于每组测试数据,输出最大子矩阵的大小。

样例输入:
4
0 -2 -7 0
9 2 -6 2
-4 1 -4  1
-1 8  0 -2
样例输出:
15
来源:
2008年北京大学软件所计算机研究生机试真题

思路:

应该有效的利用缓存,避免重复运算。

与1102题非常类似,详见我的博客http://blog.csdn.net/thudaliangrx/article/details/49363651

代码1是我的代码,代码2是更优的别人的代码。


代码1:

#include <stdio.h>
 
#define N 100
 
int main(void)
{
    int n, i, j, ii, jj;
    int a[N][N], b[N][N];
    int max, sum;
 
    while (scanf("%d", &n) != EOF)
    {
        for(i=0; i<n; i++)
        {
            for (j=0; j<n; j++)
                scanf("%d", &a[i][j]);
        }
 
        for (j=0; j<n; j++)
        {
            for(i=0; i<n; i++)
            {
                if (i == 0)
                    b[i][j] = a[i][j];
                else
                    b[i][j] = b[i-1][j] + a[i][j];
            }
        }
 
        max = a[0][0];
        for(i=0; i<n; i++)
        {
            for (j=0; j<n; j++)
            {
                for (ii=i; ii<n; ii++)
                {
                    sum = 0;
                    for (jj=j; jj<n; jj++)
                    {
                        sum += b[ii][jj];
                        if (i > 0)
                            sum -= b[i-1][jj];
                        if (sum > max)
                            max = sum;
                    }
                }
            }
        }
 
        printf("%d\n", max);
    }
 
    return 0;
}
/**************************************************************
    Problem: 1139
    User: liangrx06
    Language: C
    Result: Accepted
    Time:310 ms
    Memory:920 kb
****************************************************************/

代码2:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int str[101][101];
int mid[101];
int n;
int sum()
{
    int i;
    int max=mid[0];
    int ans=mid[0];
   for(i=1;i<n;i++)
   {
       (mid[i]+ans>mid[i])?ans=mid[i]+ans:ans=mid[i];
       if(max<ans)  max=ans;
   }
   return max;
}
int main()
{
    int i,j,k;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                scanf("%d",&str[i][j]);
            }
        }
        int max=-200;
        int ans;
        for(i=0;i<n;i++)
        {
          memset(mid,0,n*sizeof(int ));
          for(j=i;j<n;j++)
          {
              for(k=0;k<n;k++)
              {
                  mid[k]=mid[k]+str[j][k];
              }
               ans=sum();
              if(ans>max)  max=ans;
          }
        }
        printf("%d\n",max);
    }
    return 0;
}
/**************************************************************
    Problem: 1139
    User: liangrx06
    Language: C++
    Result: Accepted
    Time:50 ms
    Memory:1060 kb
****************************************************************/


posted on 2015-10-24 12:07  梁山伯  阅读(230)  评论(0编辑  收藏  举报

导航