[ZJOI2007]棋盘制作

题目描述

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

而我们的主人公小Q,正是国际象棋的狂热爱好者。作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W决定将棋盘扩大以适应他们的新规则。

小Q找到了一张由N \times MN×M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种颜色之一。小Q想在这种纸中裁减一部分作为新棋盘,当然,他希望这个棋盘尽可能的大。

不过小Q还没有决定是找一个正方形的棋盘还是一个矩形的棋盘(当然,不管哪种,棋盘必须都黑白相间,即相邻的格子不同色),所以他希望可以找到最大的正方形棋盘面积和最大的矩形棋盘面积,从而决定哪个更好一些。

于是小Q找到了即将参加全国信息学竞赛的你,你能帮助他么?

输入输出格式

输入格式:

包含两个整数NN和MM,分别表示矩形纸片的长和宽。接下来的NN行包含一个N \ \times MN ×M的0101矩阵,表示这张矩形纸片的颜色(00表示白色,11表示黑色)。

输出格式:

包含两行,每行包含一个整数。第一行为可以找到的最大正方形棋盘的面积,第二行为可以找到的最大矩形棋盘的面积(注意正方形和矩形是可以相交或者包含的)。

输入输出样例

输入样例#1:

3 3

1 0 1

0 1 0

1 0 0

输出样例#1:

4

6

说明

对于\(20\%\)的数据,\(N, M ≤ 80N,M≤80\)

对于\(40\%\)%的数据,\(N, M ≤ 400N,M≤400\)

对于\(100\%\)的数据,\(N, M ≤ 2000N,M≤2000\)

Solution

在这之前,我们先认识一个数据结构-单调栈

单调栈在计算最大子矩阵这一方面非常好用

那么单调栈是什么呢?

其实顾名思义,就是一个保持单调性的栈

若保持单调递增

那么在碰到一个元素小于栈顶时,我们会不断弹出栈顶,直到当前元素大于栈顶,一般就是在此过程中更新答案

否则直接入栈


单调递减同理

那么来看这样一道题目:在一条水平线上方有若干个矩形,求包含于这些矩形的并集内部的最大矩形的面积(下图中的阴影部分就是答案),矩形个数\(<=10^5\)



确定了单调栈,应该很好写了吧,因为矩形的宽w[]都为1,长s[]给定

所以我们建立一个单调栈,用来保存若干个矩形,这些矩形的高度是单调递增的,从左到右依次扫描这些矩形

如果当前矩形比栈顶矩形高,直接进栈

否则不断弹出栈顶,在出栈过程中,我们累加每一个矩形的宽度之和,然后用当前矩形的高度乘以这个和,其最大值就是答案,整个出栈过程结束后,我们把高度为当前高度,宽为累加值的新矩阵入栈

大致思路就是这样,那么这道题应该稍微好想了一点吧

预处理出每一列的合法高度,然后枚举每一行,求最大子矩阵的面积大小,正方形是特殊的矩形,所以可以一并算出来

具体细节:我们如果碰到一个不合法的元素,我们就要计算当前出栈元素累加的宽度,但是由于由于长条矩形可能在满足长度递增的情况下,并不与之前一个矩形01相间,所以我们需要另一种计算方法,但是由于这种方法不是很好讲,下面给出代码,请读者画图理解一下(以后有时间在更新)

Code

#include<bits/stdc++.h>
#define rg register
#define x (h[s[top]])
#define y (pos-s[top-1]-1)
#define z min(x,y)
using namespace std;
const int N=2e3+10;
int n,m,top,ans1,ans2;
int a[N][N],s[N],h[N];
int main()
{
ios::sync_with_stdio(0);
cin>>n>>m;
for(rg int i=1;i<=n;i++)
for(rg int j=1;j<=m;j++)
cin>>a[i][j];
for(rg int i=1;i<=n;i++) {
for(rg int j=1;j<=m;j++) {
if(a[i][j]!=a[i-1][j]) h[j]++;
else h[j]=1;
}
int pos=1;
while(pos<=m) {
s[top]=pos-1,s[++top]=pos++;
while(pos<=m && a[i][s[top]]!=a[i][pos]) {
while(top && h[pos]<h[s[top]])
ans1=max(ans1,z*z),ans2=max(ans2,x*y),top--;
s[++top]=pos++;
}
while(top) ans1=max(ans1,z*z),ans2=max(ans2,x*y),top--;
}
}
cout<<ans1<<endl<<ans2<<endl;
return 0;
}

博主蒟蒻,随意转载.但必须附上原文链接

http://www.cnblogs.com/real-l/

[ZJOI2007]棋盘制作 (单调栈)的更多相关文章

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

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

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

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

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

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

  4. luogu1169 棋盘制作 (单调栈)

    先预处理出来从每个位置 以0开始 往右交替最多能放多少格 然后就相当于对每一列做HISTOGRA #include<bits/stdc++.h> #define pa pair<in ...

  5. 1057: [ZJOI2007]棋盘制作

    1057: [ZJOI2007]棋盘制作 https://www.lydsy.com/JudgeOnline/problem.php?id=1057 分析: 首先对于(i+j)&1的位置0-& ...

  6. 洛谷 P1169 [ZJOI2007]棋盘制作

    2016-05-31 14:56:17 题目链接: 洛谷 P1169 [ZJOI2007]棋盘制作 题目大意: 给定一块矩形,求出满足棋盘式黑白间隔的最大矩形大小和最大正方形大小 解法: 神犇王知昆的 ...

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

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

  8. BZOJ 1057: [ZJOI2007]棋盘制作( dp + 悬线法 )

    对于第一问, 简单的dp. f(i, j)表示以(i, j)为左上角的最大正方形, f(i, j) = min( f(i + 1, j), f(i, j + 1), f(i + 1, j + 1)) ...

  9. 悬线法 || BZOJ 1057: [ZJOI2007]棋盘制作 || Luogu P1169 [ZJOI2007]棋盘制作

    题面:P1169 [ZJOI2007]棋盘制作 题解: 基本是悬线法板子,只是建图判断时有一点点不同. 代码: #include<cstdio> #include<cstring&g ...

随机推荐

  1. Python正则表达式-基础

    Python正则表达式-基础 本文转载自昔日暖阳,原文地址:http://www.osheep.cn/4806.html python使用正则,需要先引入re模块 import re 匹配符 单个字符 ...

  2. python3 练习题100例 (二十八)打印一定范围内的素数

    题目内容: 给定一个大于2的正整数n,打印出小于n(不包括n且n不大于100)的所有素数. 要求将符合条件的输出填入一个列表中,打印的结果为该列表. 输入格式: 共一行,为一个大于2的正整数 输出格式 ...

  3. queue消息队列

    class queue.Queue(maxsize=0) #先入先出 class queue.LifoQueue(maxsize=0) #last in fisrt out  class queue. ...

  4. POJ3177 边双连通分量

    Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18580   Accepted: 7711 ...

  5. Java8新特性(一)——Lambda表达式与函数式接口

    一.Java8新特性概述 1.Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 接口中的默认方法与静态方法 6. 新时间日期 API 7. 其他新特 ...

  6. LeetCode:7. Reverse Integer(Easy)

    题目要求:将给出的整数进行逆序输出 注意:整数的最大范围-2147483648-2147483647,当翻转后的数超出范围后返回0 思路:对给出的整数除以10,取余和取整:然后对取整部分继续取余和取整 ...

  7. Django信号的使用

    https://www.cnblogs.com/renpingsheng/p/7566647.html

  8. linux手动安装flash插件

    下载好之后,将解压的文件 1,将libflashplayer.so拷到firefox的插件目录/usr/lib/firefox/browser/plugin/ sudo cp libflashplay ...

  9. eclipse返回快捷键

    1.图上第一个箭头(Ctrl + Q) 返回上一个编辑点(编辑,修改代码) 2.图上第二个箭头(Alt + Left) 返回上一个操作点(点击进入方法等操作) 3.图上第三个箭头(Alt + Righ ...

  10. Prometheus 普罗米修斯监控

    周末在家无聊 看新闻 看到关于监控的东西 拿来玩玩 试一下 感觉还蛮有意思 特此记录一下 这里只介绍客户端的配置 1:首先在POM中添加依赖 <dependency> <groupI ...