zoukankan      html  css  js  c++  java
  • 洛谷P1387最大正方形(dp,前缀和)

    题目描述

    在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长。

    输入输出格式

    输入格式:

    输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m个数字,用空格隔开,0或1.

    输出格式:

    一个整数,最大正方形的边长

    输入输出样例

    输入样例#1:
    4 4
    0 1 1 1
    1 1 1 0
    0 1 1 0
    1 1 0 1
    
    输出样例#1:
    2

    暴力A了(有技巧的暴力)
    /*
    二维前缀和枚举
    这样的水题搞了一个多小时,原来是公式背错了......
    枚举每一个子矩阵的和是否等于边长的平方 自己yy的,没想到还过了
    不算慢。 
    但其实是dp......又伤心了 
    */
    
    #include<iostream>
    #include<cstdio>
    #define maxn 101
    
    using namespace std;
    int n,m,ans,tot,cnt;
    int s[maxn][maxn],map[maxn][maxn],sum[maxn][maxn];
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=m;j++)
            {
                scanf("%d",&map[i][j]);
                s[i][j]=s[i][j-1]+map[i][j];
            }
        for(int i=1;i<=n;i++)
          for(int j=1;j<=m;j++)
            sum[i][j]=sum[i-1][j]+s[i][j];
        
        for(int i=1;i<=n;i++)
          for(int j=1;j<=m;j++)
          {
              int p=i,q=j,tmp=1;
              if(map[p][q]==1 && sum[p][q]-sum[i-1][q]-sum[p][j-1]+sum[i-1][j-1]==tmp*tmp && p<=n&&q<=m)
              {
                  while(map[p][q]==1 && sum[p][q]-sum[i-1][q]-sum[p][j-1]+sum[i-1][j-1]==tmp*tmp && p<=n&&q<=m) 
                      p++,q++,tmp++;
                ans=max(ans,p-i);
            }
          }
        printf("%d
    ",ans);
        return 0;
    }

    正解dp

    //其实方程很好想,就是没勇气写,怕给输出0.... 
    
    #include<iostream>
    #include<cstdio>
     
    using namespace std;
    int a[105][105]= {{0}},f[105][105]= {{0}},n,m,maxb=1;
    
    int minn(int a,int b,int c)
    {
        return min(min(a,b),c);
    }
    
    int main()
    {
        cin>>n>>m;
        for(int i=1; i<=n; i++)
          for(int j=1; j<=m; j++)
            cin>>a[i][j];
        for(int i=1; i<=n; i++)
          for(int j=1; j<=m; j++)
            {
                if(a[i][j]==0) continue;
                f[i][j]=minn(f[i-1][j],f[i][j-1],f[i-1][j-1])+1;
            }
        for(int i=1; i<=n; i++)
          for(int j=1; j<=m; j++)
            if(f[i][j]>maxb)
              maxb=f[i][j];    
        cout<<maxb;
    }
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    没有精神分裂的测试不是一个好家长
    防火墙中配置开放 8080端口--续上一篇
    rocketMQ(一)基础环境
    如何做一个对账系统
    通用对账系统介绍与设计(上)
    pdf转图片
    虚拟机加载类机制
    jenkins
    zookeeper和dubbo
    正则日常积累
  • 原文地址:https://www.cnblogs.com/L-Memory/p/6362307.html
Copyright © 2011-2022 走看看