题目链接

题目

题目描述

国际象棋是世界上最古老的博弈游戏之一,和中国的围棋、象棋以及日本的将棋同享盛名。

据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳。

而我们的主人公小Q,正是国际象棋的狂热爱好者。作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W决定将棋盘扩大以适应他们的新规则。

小Q找到了一张由N*M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种颜色之一。小Q想在这种纸中裁减一部分作为新棋盘,当然,他希望这个棋盘尽可能的大。

不过小Q还没有决定是找一个正方形的棋盘还是一个矩形的棋盘(当然,不管哪种,棋盘必须都黑白相间,即相邻的格子不同色),所以他希望可以找到最大的正方形棋盘面积和最大的矩形棋盘面积,从而决定哪个更好一些。于是小Q找到了即将参加全国信息学竞赛的你,你能帮助他么?

输入描述

第一行包含两个整数N和M,分别表示矩形纸片的长和宽。

接下来的N行包含一个N * M的01矩阵,表示这张矩形纸片的颜色(0表示白色,1表示黑色)。

输出描述

包含两行,每行包含一个整数。

第一行为可以找到的最大正方形棋盘的面积,

第二行为可以找到的最大矩形棋盘的面积(注意正方形和矩形是可以相交或者包含的)。

示例1

输入

3 3
1 0 1
0 1 0
1 0 0

输出

4
6

备注

对于20%的数据,N, M ≤ 80

对于40%的数据,N, M ≤ 400

对于100%的数据,N, M ≤ 2000

题解

方法一

知识点:线性dp,悬线法。

悬线法:

  1. 每个点都有独立左右延长的最大宽度。

  2. 每个点都有一个往上延长的最大高度,但最大宽度会被其他点的最大宽度限制。也就是说,这个点的高度经过的所有点的最大宽度的最小值是实际这个点的最大宽度。

  3. 对一个点先延长其高度,在取高度经过点的最大宽度的最小值,可以得到这个点的高度最大的最大矩形。

  4. 由于最大矩形一定是某个点的最大高度,及其高度经过点的最大宽度的最小值构成,所以通过这个方法一定能找到。证明如下:

    假设矩形的所有底部点的最大高度比这个矩形的高度都大,那么显然我们可以把这个矩形的高度往上延长直到这些点最大高度的最小值而不会改变宽度,可以使得矩形更大,因此最大矩形的高度一定是某个点的最大高度。那么在一个高度限制下,一定是宽度最大的矩形更大。综上,对所有点优先延长其高度,然后再是左右扩展。

  5. 要注意的是,高度,左延长,右延长,三个量一个都不能少。少了高度算不出,少了左右的一个会少算矩形,因为没有左右的传递性,左侧的最大矩形,并不一定是右侧的最大矩形,遍历到右边也许不是同一个矩形了,所以都要算。

这道题是悬线法的运用。

先预处理出每个点的左右延展的最远位置,初始化高度为 \(1\) 。

然后开始向下遍历,逐行更新。可以看到在这个规则下,也是可以满足悬线法要求的,即 1,2,3的要求(宽度不会随高度变化)。

具体细节看代码更清楚。

时间复杂度 \(O(nm)\)

空间复杂度 \(O(nm)\)

方法二

知识点:线性dp,单调栈。

悬线法能解决的问题是单调栈的子集。

这道题也能用单调栈做,只要以行为底线遍历计算最大矩形即可,先处理一行的每个点的最大高度,然后和单调栈那道直方图的题一样处理。

当然要注意每行可能有若干条底线。

时间复杂度 \(O(nm)\)

空间复杂度 \(O(nm)\)

代码

方法一

#include <bits/stdc++.h>

using namespace std;

bool dt[2007][2007];
int l[2007][2007], r[2007][2007], u[2007][2007];///有且仅有三个即可 int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
cin >> dt[i][j], l[i][j] = r[i][j] = j, u[i][j] = 1;
for (int i = 1;i <= n;i++)///水平左最长
for (int j = 2;j <= m;j++)
if (dt[i][j - 1] != dt[i][j]) l[i][j] = l[i][j - 1];
for (int i = 1;i <= n;i++)///水平右最长
for (int j = m - 1;j >= 1;j--)
if (dt[i][j] != dt[i][j + 1]) r[i][j] = r[i][j + 1];
int ans1 = 0, ans2 = 0;
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= m;j++) {
if (i > 1 && dt[i - 1][j] != dt[i][j]) {///高度优先的向下传递更新
u[i][j] = u[i - 1][j] + 1;
l[i][j] = max(l[i][j], l[i - 1][j]);
r[i][j] = min(r[i][j], r[i - 1][j]);
}
int a = r[i][j] - l[i][j] + 1;
ans1 = max(ans1, min(a, u[i][j]) * min(a, u[i][j]));
ans2 = max(ans2, a * u[i][j]);
}
}
cout << ans1 << '\n' << ans2 << '\n';
return 0;
}

方法二

#include <bits/stdc++.h>

using namespace std;

bool dt[2007][2007];
int l[2007], r[2007], u[2007]; int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
cin >> dt[i][j];
int ans1 = 0, ans2 = 0;
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= m;j++) {
if (i > 1 && dt[i - 1][j] != dt[i][j]) u[j]++;
else u[j] = 1;
}
for (int j = 1;j <= m;j++) {
stack<int> s;
int k;
///不必再考虑上一层同列的扩展长度取最小值
///因为如果这层底部能扩展,则说明底部元素不同,则同一高度元素一定不同
///因此长度和高度是相匹配的,不需要考虑上一次长度
for (k = j;k <= m && (k == j || dt[i][k - 1] != dt[i][k]);k++) {
while (!s.empty() && u[k] <= u[s.top()]) s.pop();
l[k] = s.empty() ? j : s.top() + 1;///是有效位置前一个的位置,记得+1
s.push(k);
}
j = k - 1;
}
for (int j = m;j >= 1;j--) {
stack<int> s;
int k;
for (k = j;k >= 1 && (k == j || dt[i][k] != dt[i][k + 1]);k--) {
while (!s.empty() && u[k] <= u[s.top()]) s.pop();
r[k] = s.empty() ? j : s.top() - 1;///同上
s.push(k);
}
j = k + 1;
}
for (int j = 1;j <= m;j++) {
int a = r[j] - l[j] + 1;
ans1 = max(ans1, min(a, u[j]) * min(a, u[j]));
ans2 = max(ans2, a * u[j]);
}
}
cout << ans1 << '\n' << ans2 << '\n';
return 0;
}

NC20471 [ZJOI2007]棋盘制作的更多相关文章

  1. 洛谷 P1169 [ZJOI2007]棋盘制作

    2016-05-31 14:56:17 题目链接: 洛谷 P1169 [ZJOI2007]棋盘制作 题目大意: 给定一块矩形,求出满足棋盘式黑白间隔的最大矩形大小和最大正方形大小 解法: 神犇王知昆的 ...

  2. BZOJ1057 [ZJOI2007]棋盘制作(极大化思想)

    1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 1848  Solved: 936 [Submit][Sta ...

  3. bzoj 1057: [ZJOI2007]棋盘制作 单调栈

    题目链接 1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 2027  Solved: 1019[Submit] ...

  4. 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)) ...

  5. 悬线法 || BZOJ 1057: [ZJOI2007]棋盘制作 || Luogu P1169 [ZJOI2007]棋盘制作

    题面:P1169 [ZJOI2007]棋盘制作 题解: 基本是悬线法板子,只是建图判断时有一点点不同. 代码: #include<cstdio> #include<cstring&g ...

  6. P1169 [ZJOI2007]棋盘制作 && 悬线法

    P1169 [ZJOI2007]棋盘制作 给出一个 \(N * M\) 的 \(01\) 矩阵, 求最大的正方形和最大的矩形交错子矩阵 \(n , m \leq 2000\) 悬线法 悬线法可以求出给 ...

  7. [luogu P1169] [ZJOI2007]棋盘制作

    [luogu P1169] [ZJOI2007]棋盘制作 题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的 ...

  8. 1057: [ZJOI2007]棋盘制作

    1057: [ZJOI2007]棋盘制作 https://www.lydsy.com/JudgeOnline/problem.php?id=1057 分析: 首先对于(i+j)&1的位置0-& ...

  9. 【BZOJ 1057】 1057: [ZJOI2007]棋盘制作

    1057: [ZJOI2007]棋盘制作 Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的 ...

随机推荐

  1. django三板斧与request对象方法与ORM

    目录 django三板斧 HttpResponse() render() redirect() 网页获取静态文件样式 request对象方法 post请求问题 针对get请求和post请求执行不同代码 ...

  2. MQ 简介

    每日一句 You must try things that may not work. And you must not let anyone define your limits because o ...

  3. CF1485E Move and Swap

    题意:Move and Swap 很好的题呢 n个节点的树,根为1,所有叶子的深度都是D,一开始根节点上有两个颜色分别微R,B的球,你执行下列操作D-1次: 1.R点跳到子树内 2.B点跳到下一层的任 ...

  4. 开源流程引擎Camunda BPM如何扩展数据库表

    前言 在使用开源流程引擎(如:JBPM.Activiti.Flowable.Camunda等)的时候,经常会遇到这样的需求,我们需要按照业务需求增加一张数据库的表,而且这张表是跟工作流引擎有交互的(注 ...

  5. 关于个人全栈项目【臻美IT】博客类出现的问题以及解决方法

    每做一个项目,要记得写下心得哦,别偷懒啊!先上网址:https://www.maomin.club/ 这个项目属于博客类的,因为百度审核的问题就大体做了下,就当来练练手,里面文章链接的是CSDN的博客 ...

  6. SAP 定义客户端

    SCC4  定义客户端 点击新建条目按钮  Client(客户端) R 200 Client Name(客户端名称) O   City(城市) R   Logical system(逻辑系统) R   ...

  7. VisionPro · C# · 加载与保存取像工具

    VisionPro 项目程序设计,取像工具可被包含在工具包内被调用,一般,为了满足程序取像可以实现单次取像,循环取像,实时取像等多方面应用,会将取像工具独立打包. 加载代码: 1 using Syst ...

  8. 不要使用短路逻辑编写 stl sorter 多条件比较

    前言 最近工期紧.任务多,没有时间更新博客,就水一期吧.虽然是水,也不能太水,刚好最近工作中遇到一个 sorter 多条件排序的问题,花费了半天时间来定位解决,就说说它吧. 背景 公司产品是一个跨端的 ...

  9. centos系统和Ubuntu系统命令区别以及常见操作

    目录 一.前言 二.系统环境 三.命令区别 3.1 使用习惯和命令区别 3.2 服务管理的区别 3.3 软件包信息区别 四.Ubuntu系统常见操作 4.1 Ubuntu系统apt和apt-get的区 ...

  10. 《A Neural Algorithm of Artistic Style》理解

    在美术中,特别是绘画,人类掌握了通过在图像的内容和风格间建立复杂的相互作用从而创造独特的视觉体验的技巧.到目前为止,这个过程的算法基础是未知的,也没有现存的人工系统拥有这样的能力.然而在视觉感知的其他 ...