luogu 1169 棋盘制作(单调栈/悬线)
luogu 1169 棋盘制作(单调栈/悬线)
国际象棋是世界上最古老的博弈游戏之一,和中国的围棋、象棋以及日本的将棋同享盛名。据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳。而我们的主人公小Q,正是国际象棋的狂热爱好者。作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W决定将棋盘扩大以适应他们的新规则。小Q找到了一张由N*M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种颜色之一。小Q想在这种纸中裁减一部分作为新棋盘,当然,他希望这个棋盘尽可能的大。不过小Q还没有决定是找一个正方形的棋盘还是一个矩形的棋盘(当然,不管哪种,棋盘必须都黑白相间,即相邻的格子不同色),所以他希望可以找到最大的正方形棋盘面积和最大的矩形棋盘面积,从而决定哪个更好一些。于是小Q找到了即将参加全国信息学竞赛的你,你能帮助他么?N, M ≤ 2000。
首先,一个是棋盘的矩阵,满足相邻两个元素颜色不同。假设左上角的(1,1)是白色的格子。那么易证,横纵坐标之和是偶数的格子是白色的,是奇数的各自是黑色的。所以逆向思维,只要把给定的矩阵,横纵坐标之和同模2的一种格子反色,问题就变成了求最大的同色矩阵和同色正方形。这是最大子矩阵问题。用单调栈可以做,不过比悬线法烦一些。下面我来介绍一下悬线法。
悬线就是一端贴着不可算入矩形的区域(墙壁)的线。首先,一个最大子矩阵中一定有悬线,不然这个矩阵是可以再扩张的。所以,我们只要枚举所有悬线即可。首先n^2预处理出每个点向上向下能扩展的最大距离。然后从左向右,从右向左分别枚举一遍所有悬线(横向的),找出最大值即可。详见代码。
还有,个人感觉这种题目的思路很重要,就是把求最优解,转化为求出每个元素作为基础的最优值,然后取最优值中的最优值作为答案。
#include <cstdio>
using namespace std;
const int maxn=2005, INF=1e9;\
typedef int inta2[maxn][maxn];
int n, m, ans1, ans2, begin, minup, mindown;
inta2 a, up, down;
int max(int x, int y){ return x<y?y:x; }
int min(int x, int y){ return x<y?x:y; }
int sqr(int x){ return x*x; }
int main(){
scanf("%d%d", &n, &m);
for (int i=1; i<=n; ++i) //转换棋盘
for (int j=1; j<=m; ++j){
scanf("%d", &a[i][j]);
if (i&1) a[i][j]^=1;
if (!(j&1)) a[i][j]^=1;
}
for (int i=1; i<=n; ++i)
for (int j=1; j<=m; ++j)
up[i][j]=(a[i][j]==a[i-1][j]?
up[i-1][j]+1:1);
for (int i=n; i>0; --i)
for (int j=1; j<=m; ++j)
down[i][j]=(a[i][j]==a[i+1][j]?
down[i+1][j]+1:1);
//悬线法
for (int color=0; color<=1; ++color)
for (int i=1; i<=n; ++i){
minup=mindown=INF; begin=1;
for (int j=1; j<=m; ++j){
if (a[i][j]!=color){
minup=mindown=INF;
begin=j+1; continue;
}
minup=min(minup, up[i][j]);
mindown=min(mindown, down[i][j]);
ans1=max(ans1, (minup+mindown-1)*(j-begin+1));
ans2=max(ans2, sqr(min(minup+mindown-1, j-begin+1)));
}
minup=mindown=INF; begin=m;
for (int j=m; j>0; --j){
if (a[i][j]!=color){
minup=mindown=INF;
begin=j-1; continue;
}
minup=min(minup, up[i][j]);
mindown=min(mindown, down[i][j]);
ans1=max(ans1, (minup+mindown-1)*(begin-j+1));
ans2=max(ans2, sqr(min(minup+mindown-1, begin-j+1)));
}
}
printf("%d\n%d", ans2, ans1);
return 0;
}
luogu 1169 棋盘制作(单调栈/悬线)的更多相关文章
- 洛谷P4147 玉蟾宫 单调栈/悬线法
正解:单调栈/悬线法 解题报告: ummm这题我当初做的时候一点思路也没有只会暴力出奇迹:D(啊听说暴力好像能水过去呢,,, 然后当初是看的题解,然后学了下悬线法 然后就忘了:D 然后我现在看发现看不 ...
- bzoj 1057: [ZJOI2007]棋盘制作 单调栈
题目链接 1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 2027 Solved: 1019[Submit] ...
- [ZJOI2007]棋盘制作 (单调栈)
[ZJOI2007]棋盘制作 题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8 \times 88×8大小的黑白相间 ...
- BZOJ1057[ZJOI2007]棋盘制作 [单调栈]
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...
- [洛谷P1169] [ZJOI2007] 棋盘制作 解题报告(悬线法+最大正方形)
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个 8×8 大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我 ...
- [ZJOI2007]棋盘制作 (单调栈,动态规划)
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个 8 \times 88×8 大小的黑白相间的方阵,对应八八六十四卦, ...
- luogu1169 棋盘制作 (单调栈)
先预处理出来从每个位置 以0开始 往右交替最多能放多少格 然后就相当于对每一列做HISTOGRA #include<bits/stdc++.h> #define pa pair<in ...
- luogu 3467 [POI2008]PLA-Postering 单调栈
题目描述: Description N个矩形,排成一排. 现在希望用尽量少的矩形海报Cover住它们. Input 第一行给出数字N,代表有N个矩形.N在[1,250000] 下面N行,每行给出矩形的 ...
- [P1169] 棋盘制作 &悬线法学习笔记
学习笔记 悬线法 最大子矩阵问题: 在一个给定的矩形中有一些障碍点,找出内部不包含障碍点的,边与整个矩形平行或重合的最大子矩形. 极大子矩型:无法再向外拓展的有效子矩形 最大子矩型:最大的一个有效子矩 ...
随机推荐
- [容易] A + B 问题
题目来源:http://www.lintcode.com/zh-cn/problem/a-b-problem/
- Mongo 分组后排序取时间最大的一整条数据对象
db.getCollection('product_protocol_new').aggregate([ {$sort:{"end_date":-1}}, {$group:{ _i ...
- rbx1包里机器人仿真程序的实践
git clone https://github.com/pirobot/rbx1.git 1.打开一个终端 cd ~/catkin_ws/ catkin_make source ./devel/s ...
- ZOJ - 3430 Detect the Virus —— AC自动机、解码
题目链接:https://vjudge.net/problem/ZOJ-3430 Detect the Virus Time Limit: 2 Seconds Memory Limit: 6 ...
- Vue.js devtool插件安装后无法使用的解决办法
初次使用Vue.js devtool插件的新人在安装了Vue.js devtool插件后,都会经常有一个疑问.我在chrome浏览器里面已经成功安装好Vue.js devtool插件,怎么点击后提示v ...
- C#SocketAsyncEventArgs实现高效能多并发TCPSocket通信 (服务器实现)
http://freshflower.iteye.com/blog/2285272 想着当初到处找不到相关资料来实现.net的Socket通信的痛苦与心酸, 于是将自己写的代码公布给大家, 让大家少走 ...
- python-多线程2-线程同步
线程同步: 一个场景: 一个列表里所有元素都是0,线程A从后向前把所有元素改成1,而线程B负责从前往后读取列表并打印. 那么,可能线程A开始改的时候,线程B便来打印列表了,输出就变成一半0一半1,这就 ...
- listen 56
Kettles Stop Whistling in the Dark British physicist Lord Rayleigh is best known for his discovery o ...
- P1955 [NOI2015]程序自动分析[离散化+并查集]
大水题一道,不明白为什么你谷评了个蓝.一看就是离散化,先去满足相等的条件,相等即为两点联通,或者说在同一个集合内.再看不相等,只有两元素在同一集合才不满足.裸的disjoint-set直接上,常数巨大 ...
- ACM学习历程——POJ3468 A Simple Problem with Integers(线段树)
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...