点此看题面

大致题意: 给你一个\(N*M\)的\(01\)矩阵,要求你分别求出最大的\(01\)相间的正方形和矩形(矩形也可以是正方形),并输出其面积。

题解

这题第一眼看去没什么思路,仔细想想,能发现这道题其实是一道单调栈的运用题。

我们可以先对矩阵上的每一个元素进行预处理,求出以其为底的最长的 \(01\)柱

然后对矩形(正方形)的下界进行枚举,即枚举每一行作为矩形(正方形)的下边。

此时,我们发现,只要使连续的01柱连续距离和这些\(01\)柱中最短的\(01\)柱的高度的乘积最大,就可以求出最大的矩形(最大的正方形同理)。

那么,我们该如何求出每一种情况呢?这时候就要用到单调栈

我们可以建立一个严格递增的单调栈,每当单调栈栈顶的元素被弹出,我们就求出以它为右边界的最大矩阵。可以保证这样不会遗漏正确答案。

代码

#include<bits/stdc++.h>
#define N 2000
using namespace std;
int n,m,ans1,ans2,Stack[N+5],Val[N+5],a[N+5][N+5],h[N+5][N+5];
inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0;int f=1;char ch;
while(!isdigit(ch=tc())) if(ch=='-') f=-1;
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
x*=f;
}
inline void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
int main()
{
register int i,j;
for(read(n),read(m),i=1;i<=n;++i)
for(j=1;j<=m;++j)
read(a[i][j]);
for(i=1;i<=m;++i) h[1][i]=1;
for(i=2;i<=n;++i)//预处理出以每个元素为底部的最长01柱
for(j=1;j<=m;++j)
h[i][j]=a[i-1][j]^a[i][j]?h[i-1][j]+1:1;//若其与上方的元素不同,则其可以与其上方元素构成一个01柱,否则以当前元素作为一个新的01柱
for(i=1;i<=n;++i)//枚举矩形的下界
{
int top,num;//top记录栈顶,num记录当前元素最大能达到的距离
a[i][m+1]=a[i][m]^1,h[i][m+1]=0,Stack[top=1]=1,Val[1]=h[i][1];
for(j=2;j<=m+1;++j)
{
num=j;
if(!(a[i][j]^a[i][j-1]))//比较当前元素与前面的元素的异同,若相同,则清空栈并更新ans
{
while(top)
{
ans1=max(ans1,min(Val[top],j-Stack[top]));//先记录正方形的边长,最后再将其平方
ans2=max(ans2,Val[top]*(j-Stack[top]));
--top;
}
}
while(top&&h[i][j]<=Val[top])//由于要严格满足单调递增,所以要将栈中大于等于当前元素的元素弹出
{
ans1=max(ans1,min(Val[top],j-Stack[top]));
ans2=max(ans2,Val[top]*(j-Stack[top]));
num=Stack[top--];
}
Stack[++top]=num,Val[top]=h[i][j];//将当前元素加入栈
}
}
return write(ans1*ans1),putchar('\n'),write(ans2),0;
}

【BZOJ1057】[ZJOI2007] 棋盘制作(单调栈的运用)的更多相关文章

  1. BZOJ1057[ZJOI2007]棋盘制作 [单调栈]

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...

  2. bzoj 1057: [ZJOI2007]棋盘制作 单调栈

    题目链接 1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 2027  Solved: 1019[Submit] ...

  3. [ZJOI2007]棋盘制作 (单调栈)

    [ZJOI2007]棋盘制作 题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8 \times 88×8大小的黑白相间 ...

  4. [ZJOI2007]棋盘制作 (单调栈,动态规划)

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个 8 \times 88×8 大小的黑白相间的方阵,对应八八六十四卦, ...

  5. BZOJ1057 [ZJOI2007]棋盘制作(极大化思想)

    1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 1848  Solved: 936 [Submit][Sta ...

  6. BZOJ1057 [ZJOI2007]棋盘制作 【最大同色矩形】

    1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 3248  Solved: 1636 [Submit][St ...

  7. 【单调栈 动态规划】bzoj1057: [ZJOI2007]棋盘制作

    好像还有个名字叫做“极大化”? Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的 ...

  8. BZOJ1057 [ZJOI2007]棋盘制作

    Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应 ...

  9. bzoj1057: [ZJOI2007]棋盘制作--最大子矩阵

    既然要求最大01子矩阵,那么把应该为0的位置上的数取反,这样就变成求最大子矩阵 最大子矩阵可以用单调栈 #include<stdio.h> #include<string.h> ...

  10. bzoj1057: [ZJOI2007]棋盘制作 [dp][单调栈]

    Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应 ...

随机推荐

  1. spring boot jpa 使用<S extends T> List<S> findAll(Example<S> example)查询数据

    直接上代码 //查询条件对象 TinventivePrinciple time = new TinventivePrinciple(); //设置需要查询的条件(赋值) time.setIsTime( ...

  2. 【转】C#里partial关键字的作用

    源地址:http://www.cnblogs.com/OpenCoder/archive/2009/10/27/1590328.html

  3. CentOS 6.6 x64安装TensorFlow

    CentOS 6.6 x64安装TensorFlow升级Python到2.7(系统自带Python版本为2.6) // 安装编译工具 $ yum -y install gcc automake aut ...

  4. maven项目打包分析及打包后war包缺少配置文件报错的原因分析,使用progard混淆时配置分析

    1.maven打包: 一直以来我都没太注意过在myeclipse下使用run as来clean居然对项目的target目录没有进行操作,要让操作有效,需要进入到maven build...选项下,进行 ...

  5. 利用xsltproc转换jtl报告到html报告

    使用Jmeter测试完后并不能直接生成html报告,而是jtl报告.这里我们可以用xsltproc来解决. xsltproc是由DanielVeillard用来C语言编写的是一个快速XSLT引擎,   ...

  6. CSS十一问——好奇心+刨根问底=CSSer

    最近有时间,想把酝酿的几篇博客都写出来,今天前端小学生带着10个问题,跟大家分享一下学习CSS的一些体会,我觉得想学好CSS,必须保持一颗好奇心和刨根问底的劲头,而不是复制粘贴,得过且过.本人能力有限 ...

  7. codeforces round 472(DIV2)D Riverside Curio题解(思维题)

    题目传送门:http://codeforces.com/contest/957/problem/D 题意大致是这样的:有一个水池,每天都有一个水位(一个整数).每天都会在这一天的水位上划线(如果这个水 ...

  8. Sharepoint 根据文件相对路径获取、操作SPFolder

    public AjaxResult LoadDocInfo(HttpContext httpContext) { var result = new ArrayList(); try { var org ...

  9. 什么是SG?+SG模板

    先,定义一下 状态Position P 先手必败 N x先手必胜 操作方法: 反向转移 相同状态 不同位置 的一对 相当于无 对于ICG游戏,我们可以将游戏中每一个可能发生的局面表示为一个点.并且若存 ...

  10. mysql存储过程详解实例

    mysql存储过程详解 1.      存储过程简介 我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL ...