zoukankan      html  css  js  c++  java
  • king's trouble II SCU

    Time Limit: 1000 MS Memory Limit: 131072 K

    Description

    Long time ago, a king occupied a vast territory.
    Now there is a problem that he worried that he want to choose a largest square of his territory to build a palace.
    Can you help him?

    For simplicity, we use a matrix to represent the territory as follows:
    0 0 0 0 0
    0 1 0 1 0
    1 1 1 1 0
    0 1 1 0 0
    0 0 1 0 0

    Every single number in the matrix represents a piece of land, which is a 1*1 square
    1 represents that this land has been occupied
    0 represents not

    Obviously the side-length of the largest square is 2


    Input

    The first line of the input contains a single integer t (1≤t≤5) — the number of cases.
    For each case
    The first line has two integers N and M representing the length and width of the matrix
    Then M lines follows to describe the matrix
    1≤N,M≤1000

    Output

    For each case output the the side-length of the largest square

    Sample Input

    2
    5 5
    0 0 0 0 0
    0 1 0 1 0
    1 1 0 1 0
    0 1 1 0 0
    0 0 1 0 0
    5 5
    0 0 0 0 0
    0 1 0 1 0
    1 1 1 1 0
    0 1 1 0 0
    0 0 1 0 0

    Sample Output

    1
    2

    #include<queue>
    #include<stack>
    #include<vector>
    #include<math.h>
    #include<cstdio>
    #include<numeric>//STL数值算法头文件
    #include<stdlib.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    #include<functional>//模板类头文件
    using namespace std;
    
    const int INF=1e9+7;
    const int maxn=1010;
    typedef long long ll;
    
    
    //单调栈
    //先做 poj 2559后再看单调栈可能会好理解一点
    int a[1010][1010];
    struct node
    {
        int idx,num;//下标和延伸值
    };
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            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])
                        a[i][j]+=a[i-1][j];
                }
                a[i][m+1]=-1;
            }
            int ans=-1;
            for(int i=1; i<=n; i++)
            {
                int top=0;
                node vis[1010];
                for(int j=1; j<=m+1; j++)
                {
                    if(top==0)
                    {
                        vis[top].idx=j,vis[top++].num=1;
    
                    }
                    else
                    {
                        printf("top=%d
    ",top);
                        int v=vis[top-1].idx,cont=0;
                        while(top>0&&a[i][v]>=a[i][j])
                        {
                            cont+=vis[top-1].num;
                            if(cont>=a[i][v])
                                ans=max(ans,a[i][v]);
                            top--;
                            v=vis[top-1].idx;
                        }
                        vis[top].idx=j,vis[top++].num=cont+1;
                        printf("vis[top].idx=%d vis[top].num=%d
    ",vis[top-1].idx,vis[top-1].num);
                    }
                }
            }
            printf("%d
    ",ans);
        }
    }
    
    
    //暴力
    //先把每一列累加,类似于条形图,然后从每一行的开头开始遍历到每一行结束,
    //(不过是因为这一题的后台数据水,
    //暴力才能过,所以如果数据范围太大不推荐暴力)
    int mp[maxn][maxn];
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n,m,x;
            memset(mp,0,sizeof(mp));
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=m; j++)
                {
                    scanf("%d",&x);
                    if(x&&mp[i-1][j])
                        mp[i][j]=mp[i-1][j]+1;
                    else
                        mp[i][j]=x;
                }
            }
            int maxx=0;
            int k=1;//代表此时最大的面积
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=m; j++)
                {
                    if(mp[i][j]>=k)
                    {
                        int p=0;
                        for(; mp[i][p+j]>=k; p++);//每一行从头遍历到尾
                        if(p>=k)
                        {
                            maxx=k;
                            k++;
                        }
                    }
                }
            }
            printf("%d
    ",maxx);
        }
        return 0;
    }
    
    
    
    //动规
    //以每一个点作为正方形的右上角,
    //每次取四个角的最小值加一即为此时的最大面积(因为本题规定的每个矩形面积为1)
    //自己画图可以理解的
    int a[maxn][maxn];
    int dp[maxn][maxn];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            memset(dp,0,sizeof(dp));
            for(int i=0; i<n; i++)
                for(int j=0; j<m; j++)
                    scanf("%d",&a[i][j]);
            int ans=0;
            for(int i=1; i<n; i++)
            {
                for(int j=1; j<m; j++)
                {
                    if(a[i][j]==1)
                    {
                        dp[i][j]=min(dp[i][j-1],min(dp[i-1][j-1],dp[i-1][j]))+1;
                    }
                    ans=max(ans,dp[i][j]);
                }
            }
            printf("%d
    ",ans);
        }
    }
    
  • 相关阅读:
    简单的理解原型链
    react->Context笔记
    工作上git指令小结
    vue 绑定事件如何传递参数的同时拿到事件对象
    vsCode卸载后重新安装,以前的插件有没有效果的解决方法
    mongo 分组 aggregation
    Redisson分布式锁原理
    Virtual server server already has a web module live-mix-1.0.2-t230 loaded at / therefore web module
    二进制中 1 的个数
    替换空格
  • 原文地址:https://www.cnblogs.com/nyist-xsk/p/7264853.html
Copyright © 2011-2022 走看看