• 九度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
    ", 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
    ",max);
        }
        return 0;
    }
    /**************************************************************
        Problem: 1139
        User: liangrx06
        Language: C++
        Result: Accepted
        Time:50 ms
        Memory:1060 kb
    ****************************************************************/


    编程算法爱好者。
  • 相关阅读:
    洛谷P5245 【模板】多项式快速幂
    洛谷P5205 【模板】多项式开根(FFT)
    laravel 数据库连接Mysql
    laravel V层引入css 和js方法
    laravel V层
    小程序地区时间自定义选择器 picker
    点击a标签 跳到当前页面指定div
    图片上下居中
    小程序消除图片下边距的三个方法
    百度地图定位
  • 原文地址:https://www.cnblogs.com/liangrx06/p/5083892.html
Copyright © 2020-2023  润新知