zoukankan      html  css  js  c++  java
  • [BZOJ]1057: [ZJOI2007]棋盘制作

    FallDream dalao随手切 赶紧上他博客学习了一个。

    题目大意:给出一个n*m的01矩阵,求最大的子正方形/矩形,满足任意相邻格子不同。(n,m<=2000)

    思路:把行列坐标相加为偶数的异或上1,题目变成求最大的全为0或1的子正方形/矩形,我们分别处理,预处理出每个格子向右有多少连续的0/1,枚举列,用个单调栈维护和统计答案(维护上升序列),复杂度O(nm)。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    inline int read()
    {
        int x;char c;
        while((c=getchar())<'0'||c>'9');
        for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=(x<<3)+(x<<1)+c-'0';
        return x;
    }
    #define MN 2000
    int n,m,a[MN+5][MN+5],f[MN+5][MN+5],ans1,ans2,q[MN+5],qx[MN+5],qn;
    inline int sqr(int x){return x*x;}
    void solve(int x)
    {
        int i,j;
        for(i=1;i<=n;++i)for(j=m;j;--j)f[i][j]=a[i][j]==x?f[i][j+1]+1:0;
        for(i=1;i<=m;++i)for(j=qn=0;j++<=n;qx[++qn]=f[j][i])
            for(q[qn+1]=j;qn&&f[j][i]<qx[qn];--qn)
                ans1=max(ans1,sqr(min(j-q[qn],qx[qn]))),
                ans2=max(ans2,(j-q[qn])*qx[qn]);
    }
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)a[i][j]=read()^((i+j)&1);
        solve(0);solve(1);
        printf("%d
    %d",ans1,ans2);
    }
  • 相关阅读:
    HTTP 错误 403.14
    HTTP 错误 404.3
    HTTP 500
    [转]ESCAPE()、ENCODEURI()、ENCODEURICOMPONENT()区别详解
    此计算机当前已将连接限制
    一个由表结构生成表的存储过程
    微信小程序页面跳转传参
    前端性能优化术语
    get请求和post请求的区别
    从输入url到页面呈现的过程
  • 原文地址:https://www.cnblogs.com/ditoly/p/BZOJ1057.html
Copyright © 2011-2022 走看看