[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 ...
随机推荐
- 最短路径算法 1.Floyed-Warshall算法
这几周开始正式系统学习图论,新学期开始新的记录.由于二模和生物地理两门高考的临近,时间比较仓促,所以暂时跳过图论的(一)和(二),即图的储存和遍历.从最短路径算法学起,首先要学习的是Floyed-Wa ...
- python基础之try异常处理、socket套接字基础part1
异常处理 错误 程序里的错误一般分为两种: 1.语法错误,这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正 2.逻辑错误,人为造成的错误,如数据类型错误.调用方法错误等,这些解 ...
- Xshell入门教程介绍
免费软件 Xshell和 Xftp 都是 NetSarang 出品的优秀网络管理.安全传输工具.Xshell 是一个免费的安全终端仿真器,可以作为 SSH.TELNET 或 RLOGIN 的终端模拟, ...
- jpa Specification复杂查询
public List<Receipts> test(List<String> costIds){ Specification<Receipts> specific ...
- namenode处于安全模式怎么解决?
当我们在hdfs上操作文件的时候,有时候会报错 ,出现namenode in safemode namenode处于安全模式的原因: 1.NameNode发现集群中DataNode丢失达到一定 ...
- Office使用技巧(不断补充)
1.word中,第一行后面有很多空格,但把第二行的退到第一行来就删了第一行的字,为什么? 解决办法:应该是下一行开头部分是一个不可拆分的整体,上一行末尾放不下,只能放在下一行.处理方法:格式--段落- ...
- 常见bug解析-移动端
手机测试常见bug解析 1.测试时遇到“手机无响应”? 有以下几个原因: a.手机内存不足 b.android进程之间死锁引起的(就是两个进程之间) c.手机的CPU运行高引起的 可以查看手机的崩溃日 ...
- Windows系统的高效使用
1-WIndows10系统的入门使用 2-如何把系统盘的用户文件转移到其他盘 3-Windows装机软件一般有哪些? 4-Windows系统有哪些比较好用的下载器? 5-Windows系统中的播放器 ...
- 在Code::Blocks中编译和使用wxWidgets3.0.0教程
跳转至:指南,搜索 注意,编译Code :: Blocks的对wxWidgets的3.0.0链接不是很稳定,但该库至少可以被正确编译,(只是使用的时候可能会有问题):CodeBlocks开发商都在 ...
- 排查实时tail功能cpu占用过高问题
“你的python应用cpu占用快90%了!!!”,良哥朝我眨了眨布满血丝的眼睛“不会吧”,我心想:我这是好的啊 没接触过kafka的同学可以先了解下:([http://www.jasongj.com ...