[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 用装饰器写登录
# 1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件), # 要求登录成功一次,后续的函数都无需再输入用户名和密码 # FLAG = False # def login(func): ...
- 【Java】关于Spring框架的总结 (一)
本文总结一些关于Spring框架的理解,注意点及基础操作.如果有不对的地方,欢迎批评和建议.大家一起努力吧! Spring 框架简介 Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创 ...
- Java基础——内部类
一.什么是内部类 将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类 内部类所在的类在编译成功后,会出现这样两个class文件:OuterClass.class和OuterClass$In ...
- MYSQL--事务处理(转)
事务处理在各种管理系统中都有着广泛的应用,比如人员管理系统,很多同步数据库操作大都需要用到事务处理.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如 ...
- (原)MongoDB在系统中的使用
序)Nosql并不是要取代原有的数据产品,而是为不同的应用场景提供更多的选择. 一)结构类型 传统数据库的领域在于结构化文档,对于非结构化文档和半结构化文档,它能处理,但是有一定的缺陷,那么什么又是结 ...
- Lambda表达式在Kotlin中怎样工作的:setOnClickListener的转换(KAD 18)
作者:Antonio Leiva 时间:Mar 28, 2017 原文链接:https://antonioleiva.com/lambdas-kotlin-android/ 虽然,我在其它文章讲过一点 ...
- ubuntu apache2配置,包括虚拟机配置
虚拟机设置好了之后,需要在/etc/hosts里面添加 127.0.0.1 www.baidu.com 跟在windows里hosts里配置是一样的
- Python中enumerate函数用法详解
enumerate函数用于遍历序列中的元素以及它们的下标,多用于在for循环中得到计数,enumerate参数为可遍历的变量,如 字符串,列表等 一般情况下对一个列表或数组既要遍历索引又要遍历元素时, ...
- MUI scroll 定位问题
做一个微信项目,使用MUI做框架,在使用scroll定位的时候,出现了定位不准确的问题,查询了好多资料,得知他是相对定位.折腾了好久,才搞定,现在做一个笔记. mui('body').on('tap' ...
- SourceTree git的管理工具使用教程1
1SourceTree是一个window系统下的Git管理工具 2设置Git 工具——选项——Git设置 3拷贝远程的项目 新建/克隆(输入远程项目的url地址) 4验证(填写用户信息) 工具——选项 ...