• UVALive


    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2868


    用暴力也过了:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<map>
    #include<string>
    #include<set>
    #define LL long long
    #define MAX(a,b) (a>b?a:b)
    #define MIN(a,b) (a<b?a:b)
    
    using namespace std;
    
    int a[1050][1050];
    int n,m;
    int ans = 0;
    
    int test(int x, int y, int len)
    {
        for(int i = x; i<x+len; i++)
        for(int j = y; j<y+len; j++)
        {
            if(a[i][j]==0) return 0;
        }
        return 1;
    }
    
    int main()
    {
        while(scanf("%d%d",&n,&m) && (m||n))
        {
            ans = 0;
            for(int i = 1; i<=n; i++)
            for(int j = 1; j<=m; j++)
                scanf("%d",&a[i][j]);
    
            for(int i = 1; i<=n; i++)
            for(int j = 1; j<=m; j++)
            {
                if(a[i][j])
                for(int len = 1; j+len-1<=m && i+len-1<=n; len++)
                {
                    if(len<=ans)//这一步很重要,如果长度都比ans小,那再去比较也无意义了。少了这一句就少时了。
                        continue;
    
                    if(test(i,j,len))
                        ans = MAX(ans,len);
    
                    else break;
                }
            }
            printf("%d
    ",ans);
    
        }
        return 0;
    }
    



    然后使用dp,画图找找规律。dp[i][j]为当前格子作为右下角能达到的最大正方形边长,可知dp[i][j] 只与dp[i-1][j] ,dp[i][j-1] ,dp[i-1][-1j]有关。所以可以得到状态转移方程:dp[i][j] = 1 + MMIN(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #include<map>
    #include<string>
    #include<set>
    #define LL long long
    #define MAX(a,b) (a>b?a:b)
    #define MIN(a,b) (a<b?a:b)
    #define MMIN(a,b,c) (MIN(a,b)<c?MIN(a,b):c)
    
    using namespace std;
    
    int a[1050][1050];
    int dp[1050][1050];
    
    int n,m;
    int ans = 0;
    
    int main()
    {
        while(scanf("%d%d",&n,&m) && (m||n))
        {
            ans = 0;
            for(int i = 1; i<=n; i++)
            for(int j = 1; j<=m; j++)
            {
                dp[i][j] = 0;
                scanf("%d",&a[i][j]);
                if(a[i][j])
                {
                    dp[i][j] = 1 + MMIN(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]);
                }
    
                ans = MAX(dp[i][j],ans);
            }
           printf("%d
    ",ans);
        }
        return 0;
    }


  • 相关阅读:
    JavaWeb 【介绍】
    Python3 【解析库XPath】
    Python【类编程】
    Python3【正则表达式】
    Java GUI【记事本】
    Java 【笔记本】
    Python3 【requests使用】
    Java 【食品库存管理】
    AGC027 C
    AGC027 A
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538747.html
Copyright © 2020-2023  润新知