rainyroad

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

题意:给你一个0 1 矩阵,现在让你从中找一个正方形,对角线上全是1,其余部分全是0。问你这个正方形的对角线最大可以是多少。

思路:以矩阵中的坐标位置来作为正方形右下角的下标来作为一个状态,dp[ i ][ j ]表示以 i,j为右下角下标的正方形。

那么这个正方形的对角线长由与其相邻的三个正方形推出,dp[ i-1 ][ j ],dp[ i ][ j-1 ],dp[ i-1 ][ j-1 ],取其中的最下值+1.

这中方形的问题好像经常用这四个点做文章。。

#include<bits/stdc++.h>
using namespace std;

int n,m;
int s1[2509][2509],s2[2509][2509];
int dp[2509][2509];
int ans=0;
int a[2509][2509];

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
    {
        scanf("%d",&a[i][j]);
        if(!a[i][j])
        {
            s1[i][j]=s1[i][j-1]+1;
            s2[i][j]=s2[i-1][j]+1;
        }
        else if(a[i][j])
        {
            dp[i][j]=min(min(s1[i][j-1],s2[i-1][j]),dp[i-1][j-1])+1;
            ans=max(ans,dp[i][j]);
        }

    }

    memset(s1,0,sizeof s1);
    memset(s2,0,sizeof s2);
    memset(dp,0,sizeof dp);

    for(int i=1;i<=n;i++)
     for(int j=m;j>=1;j--)
    {
        if(!a[i][j])
        {
            s1[i][j]=s1[i][j+1]+1;
            s2[i][j]=s2[i-1][j]+1;
        }
        else if(a[i][j])
        {
            dp[i][j]=min(min(s1[i][j+1],s2[i-1][j]),dp[i-1][j+1])+1;
            ans=max(ans,dp[i][j]);
        }
    }

    cout<<ans;

    return 0;
}

 

posted on 2019-07-23 10:29  rainyroad  阅读(172)  评论(0编辑  收藏  举报