1057: [ZJOI2007]棋盘制作

Time Limit: 20 Sec  Memory Limit: 162 MB

Submit: 3248  Solved: 1636

[Submit][Status][Discuss]

Description

  国际象棋是世界上最古老的博弈游戏之一,和中国的围棋、象棋以及日本的将棋同享盛名。据说国际象棋起源
于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳。而我们的主人公小Q,
正是国际象棋的狂热爱好者。作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W决定
将棋盘扩大以适应他们的新规则。小Q找到了一张由N*M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种
颜色之一。小Q想在这种纸中裁减一部分作为新棋盘,当然,他希望这个棋盘尽可能的大。不过小Q还没有决定是找
一个正方形的棋盘还是一个矩形的棋盘(当然,不管哪种,棋盘必须都黑白相间,即相邻的格子不同色),所以他
希望可以找到最大的正方形棋盘面积和最大的矩形棋盘面积,从而决定哪个更好一些。于是小Q找到了即将参加全
国信息学竞赛的你,你能帮助他么?

Input

  第一行包含两个整数N和M,分别表示矩形纸片的长和宽。接下来的N行包含一个N * M的01矩阵,表示这张矩形
纸片的颜色(0表示白色,1表示黑色)。

Output

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

Sample Input

3 3

1 0 1

0 1 0

1 0 0

Sample Output

4

6

HINT

N, M ≤ 2000

好像以前写过?

再写一遍加深印象

开一个sum[i][j]表示位置(i,j)能向右同色延伸的最大长度

我们先定下矩形的左边所在列,对该列中的点按向右延伸长度降序排序,然后枚举每个点

这样子每次枚举出的点对应的宽一定是当前最小的【宽】,再用并查集维护其向上向下最长延伸距离【长】,

我们就可以得出以该点为向右为宽的最大矩形面积

而我们最后求出的矩形的宽一定会受其中至少一个点向右延伸长度的束缚

当我们枚举到答案中影响宽的那一个点的时候就一定能更新出最优答案

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 2005,maxm = 100005,INF = 1000000000;
inline int RD(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
return out * flag;
}
int A[maxn][maxn],sum[maxn][maxn],N,M,up[maxn],down[maxn],ans1 = 0,ans2 = 0;
bool vis[maxn];
struct node{int i,len;}e[maxn];
inline bool operator < (const node& a,const node& b){return a.len > b.len;}
inline int findu(int u){return u == up[u] ? u : up[u] = findu(up[u]);}
inline int findd(int u){return u == down[u] ? u : down[u] = findd(down[u]);}
void solve(){
for (int i = 1; i <= N; i++){
sum[i][M] = 1;
for (int j = M - 1; j > 0; j--)
sum[i][j] = A[i][j] == A[i][j + 1] ? sum[i][j + 1] + 1 : 1;
}
for (int j = 1; j <= M; j++){
for (int i = 1; i <= N; i++){
e[i].i = i; e[i].len = sum[i][j]; down[i] = up[i] = i; vis[i] = false;
}
sort(e + 1,e + 1 + N);
for (int i = 1; i <= N; i++){
int k = e[i].i; vis[k] = true;
//printf("(%d,%d) len = %d %d\n",k,j,e[i].len,ans1);
if (k > 1 && vis[k - 1] && A[k - 1][j] == A[k][j]){
up[k] = findu(k - 1);
down[k - 1] = k;
}
if (k < N && vis[k + 1] && A[k + 1][j] == A[k][j]){
down[k] = findd(k + 1);
up[k + 1] = k;
}
int u = findu(k),d = findd(k),ed = min(e[i].len,d - u + 1);
//printf("%d %d\n",u,d);
ans1 = max(ans1,ed * ed);
ans2 = max(ans2,e[i].len * (d - u + 1));
}
}
}
int main(){
N = RD(); M = RD();
REP(i,N) REP(j,M) A[i][j] = RD() ^ ((i & 1) ^ (j & 1));
//REP(i,N){REP(j,M) cout<<A[i][j]<<' ';cout<<endl;}
solve();
cout<<ans1<<endl<<ans2<<endl;
return 0;
}

BZOJ1057 [ZJOI2007]棋盘制作 【最大同色矩形】的更多相关文章

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

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

  2. BZOJ1057[ZJOI2007]棋盘制作 [单调栈]

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...

  3. BZOJ1057 [ZJOI2007]棋盘制作

    Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应 ...

  4. 【单调栈 动态规划】bzoj1057: [ZJOI2007]棋盘制作

    好像还有个名字叫做“极大化”? Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的 ...

  5. bzoj1057: [ZJOI2007]棋盘制作 [dp][单调栈]

    Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应 ...

  6. 洛谷 P1169||bzoj1057 [ZJOI2007]棋盘制作

    洛谷P1169 bzoj1057 这个题目跟最大全0子矩阵是类似的.正方形的话,只要把任意极大子正方形(”极大“定义见后面的”论文“)当成把某个极大子矩形去掉一块变成正方形即可,容易解决. 解法1:看 ...

  7. 2018.10.19 bzoj1057: [ZJOI2007]棋盘制作(悬线法)

    传送门 悬线法板题. 如果只求最大矩形面积那么跟玉蟾宫是一道题. 现在要求最大正方形面积. 所以每次更新最大矩形面积时用矩形宽的平方更新一下正方形答案就行了. 代码: #include<bits ...

  8. bzoj1057: [ZJOI2007]棋盘制作--最大子矩阵

    既然要求最大01子矩阵,那么把应该为0的位置上的数取反,这样就变成求最大子矩阵 最大子矩阵可以用单调栈 #include<stdio.h> #include<string.h> ...

  9. bzoj1057: [ZJOI2007]棋盘制作(悬线法)

    题目要求纵横坐标和奇偶性不同的点取值不同,于是我们把纵横坐标和奇偶性为1的点和0的点分别取反,就变成经典的最大全1子矩阵问题了,用悬线法解决. #include<iostream> #in ...

随机推荐

  1. 数据分析处理库Pandas——时间

    时间戳 向后推的时间戳 备注:五天后的时间. 指定日期和时间 时间的Series结构 按要求显示时间(开始时间,时间间隔,时间个数) 转换为时间格式,并设置时间列为索引列 方法一 方法二 筛选显示 方 ...

  2. 网站apache环境S2-057漏洞 利用POC 远程执行命令漏洞复现

    S2-057漏洞,于2018年8月22日被曝出,该Struts2 057漏洞存在远程执行系统的命令,尤其使用linux系统,apache环境,影响范围较大,危害性较高,如果被攻击者利用直接提权到服务器 ...

  3. Linux中程序的编译和链接过程

    1.从源码到可执行程序的步骤:预编译.编译.链接.strip 预编译:预编译器执行.譬如C中的宏定义就是由预编译器处理,注释等也是由预编译器处理的. 编译: 编译器来执行.把源码.c .S编程机器码. ...

  4. POJ2186 强连通分量+缩点

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 40234   Accepted: 16388 De ...

  5. rhel6.4 根目录扩容

    状况:根目录容量不足 解决:扩容根目录 ====================================================== 解决步骤: 1. 将新的磁盘加入服务器 2. 使用 ...

  6. h5调试工具

    1.Safari:iPhone 调试利器,查错改样式首选: 2.iOS 模拟器:不需要真机,适合调试 Webview 和 H5 有频繁交互的功能页面: 3.Charles: Mac OS 系统首选的抓 ...

  7. SQL Server中2008及以上 ldf 文件过大的解决方法

    在SQL Server中经常遇到事务日志变大的情况,除了将数据库设置为“自动收缩”外,还可以使用下面的SQL命令进行快速清除数据库中的事务日志,命令如下:  - 第一步:清空日志  ALTER DAT ...

  8. 原生js实现五子棋

    为什突然做这个,因为这是个笔试题,拖了一个月才写(最近终于闲了O(∩_∩)O),废话不多说,说说这个题吧 题目要求 编写一个单机[五子棋]游戏,要求如下: 1.使用原生技术实现,兼容 Chrome 浏 ...

  9. Qt Qml 汽车仪表

    上一个原文连接http://blog.csdn.net/z609932088/article/details/53946245 参考资料连接:链接: https://pan.baidu.com/s/1 ...

  10. C++学习006-条件运算符

    这里我也理解的不咋的,大致意思应该就是根据运算符号 的优先级不同来解决的 条件运算符是其中一部分,而条件运算符具有右结合性,当一个表达式中出现多个条件运算符时,应该将位于最右边的问号与理他最近的冒号配 ...