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] 棋盘制作 &悬线法学习笔记
学习笔记 悬线法 最大子矩阵问题: 在一个给定的矩形中有一些障碍点,找出内部不包含障碍点的,边与整个矩形平行或重合的最大子矩形. 极大子矩型:无法再向外拓展的有效子矩形 最大子矩型:最大的一个有效子矩 ...
随机推荐
- POJ - 3278 Catch That Cow 【BFS】
题目链接 http://poj.org/problem?id=3278 题意 给出两个数字 N K 每次 都可以用三个操作 + 1 - 1 * 2 求 最少的操作次数 使得 N 变成 K 思路 BFS ...
- 基础 PHP 语法
PHP 脚本在服务器上执行,然后向浏览器发送回纯 HTML 结果. 基础 PHP 语法 PHP 脚本可放置于文档中的任何位置. PHP 脚本以 <?php 开头,以 ?> 结尾: < ...
- Android Weekly Notes Issue #321
Android Weekly Issue #321 August 5th, 2018. Android Weekly Issue #321 本期内容包括: 开源项目Plaid的改版; 使用Tensor ...
- 解决/usr/bin/ld: cannot find -lmysqlclient错误
类似/usr/bin/ld: cannot find -xxxx的错误有很多, 首先我们可以最简单的判断一下: 这类情况一般是由于缺乏某某库文件, 又或者可能是由于已存在的库问题版本不对造成的 一般都 ...
- 1.2 Data Abstraction(算法 Algorithms 第4版)
1.2.1 package com.qiusongde; import edu.princeton.cs.algs4.Point2D; import edu.princeton.cs.algs4.St ...
- ZOJ 3640 Help Me Escape:期望dp
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3640 题意: 有一个吸血鬼被困住了,他要逃跑... 他面前有n条 ...
- linux命令学习笔记(47):iostat命令
Linux系统中的 iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视. 它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况. ...
- inteliji ---idea 如何创建scala程序配置
首先创建一个新的工程: #####################################################################################
- BZOJ2028:[SHOI2009]会场预约(线段树版)
浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html 题目传送门:https://www.lydsy.com/JudgeOnline/prob ...
- Jenkins安装配置简单使用
安装启动是十分简单的,直接去https://jenkins.io/download/下载对应的rpm包就好了,需要注意的是我们的机器上要提前有java环境,相对应要选择你java环境可以支持的jenk ...