[ZJOI2007]棋盘制作 (单调栈)
[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]棋盘制作 (单调栈)的更多相关文章
- bzoj 1057: [ZJOI2007]棋盘制作 单调栈
题目链接 1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 2027 Solved: 1019[Submit] ...
- BZOJ1057[ZJOI2007]棋盘制作 [单调栈]
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...
- [ZJOI2007]棋盘制作 (单调栈,动态规划)
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个 8 \times 88×8 大小的黑白相间的方阵,对应八八六十四卦, ...
- luogu1169 棋盘制作 (单调栈)
先预处理出来从每个位置 以0开始 往右交替最多能放多少格 然后就相当于对每一列做HISTOGRA #include<bits/stdc++.h> #define pa pair<in ...
- 1057: [ZJOI2007]棋盘制作
1057: [ZJOI2007]棋盘制作 https://www.lydsy.com/JudgeOnline/problem.php?id=1057 分析: 首先对于(i+j)&1的位置0-& ...
- 洛谷 P1169 [ZJOI2007]棋盘制作
2016-05-31 14:56:17 题目链接: 洛谷 P1169 [ZJOI2007]棋盘制作 题目大意: 给定一块矩形,求出满足棋盘式黑白间隔的最大矩形大小和最大正方形大小 解法: 神犇王知昆的 ...
- BZOJ1057 [ZJOI2007]棋盘制作(极大化思想)
1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec Memory Limit: 162 MB Submit: 1848 Solved: 936 [Submit][Sta ...
- 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)) ...
- 悬线法 || BZOJ 1057: [ZJOI2007]棋盘制作 || Luogu P1169 [ZJOI2007]棋盘制作
题面:P1169 [ZJOI2007]棋盘制作 题解: 基本是悬线法板子,只是建图判断时有一点点不同. 代码: #include<cstdio> #include<cstring&g ...
随机推荐
- python继续函数-练习(2017-8-3)
写函数,计算传入字符串中[数字].[字母].[空格] 以及 [其他]的个数 def detection(p): intcount = 0 strcount = 0 othercount = 0 spa ...
- (数据科学学习手札24)逻辑回归分类器原理详解&Python与R实现
一.简介 逻辑回归(Logistic Regression),与它的名字恰恰相反,它是一个分类器而非回归方法,在一些文献里它也被称为logit回归.最大熵分类器(MaxEnt).对数线性分类器等:我们 ...
- Word中使用宏调整表格
Dim i As Integer For i = 1 To Selection.Tables.Count Selection.Tables(i).Columns(9).Delete Selecti ...
- inline-block 空隙
IE8-9.Firefox.Safari 是4px Chrome下是8px 出现原因 标签换行引起 解决方案网上很多 但是在布局中尽量避免使用inline-block
- 「日常训练」Alena And The Heater (CFR466D2D)
题意(Codeforces 940D) 根据给定要求构建数列,求能构建出相同数列的l和r. 分析 这题写的是真的烦.一定要想到对b串要按照5个5个的看!为什么5个5个的看?因为根据题意,是先看前4个再 ...
- 【紫书】(UVa1347)Tour
继续考虑dp题目. 题意分析 其实这里只是更加仔细的做一个lrj的复读机(Orz 他分析了一个很重要的结果:如果是一个人从左到右再回来,并且每个点恰经过一次,那么等价于两个人从左到右每个点经过一次地遍 ...
- Qt Qwdget 汽车仪表知识点拆解5 标题栏图标闪烁
先贴上效果图,注意,没有写逻辑,都是乱动的 看下最上面的部分,有一些仪表图标在闪烁,如果一个一个写,也是可以实现的,不过感觉要累死的节奏 这里我写了一个我自己的Label,完了把把这些QLabel提升 ...
- eclipse返回快捷键
1.图上第一个箭头(Ctrl + Q) 返回上一个编辑点(编辑,修改代码) 2.图上第二个箭头(Alt + Left) 返回上一个操作点(点击进入方法等操作) 3.图上第三个箭头(Alt + Righ ...
- 分布式一致性算法之Paxos原理剖析
概述 Zookeeper集群中,只有一个节点是leader节点,其它节点都是follower节点(实际上还有observer节点,不参与选举投票,在这里我们先忽略,下同).所有更新操作,必须经过lea ...
- 剑指offer-二进制中1的个数11
题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. class Solution: def NumberOf1(self, n): # write code here coun ...