BZOJ1057:[ZJOI2007]棋盘制作——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=1057

https://www.luogu.org/problemnew/show/P1169

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

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

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

不过小Q还没有决定是找一个正方形的棋盘还是一个矩形的棋盘(当然,不管哪种,棋盘必须都黑白相间,即相邻的格子不同色),所以他希望可以找到最大的正方形棋盘面积和最大的矩形棋盘面积,从而决定哪个更好一些。

于是小Q找到了即将参加全国信息学竞赛的你,你能帮助他么?

参考了洛谷题解以及大量讲最大子矩阵的问题。

今天学了一天的这玩意就是为了解这道题的。

接论文的算法1和算法2,我们还可以单调栈维护dp做。

首先先把图形转换一下,引用洛谷题解。

对于图上所有的棋盘一定属于以下两种类型:

1.黑格行列奇偶性相同,白格不同

2.白格行列奇偶性相同,黑格不同

那么第一种情况的格子设为0,第二种为1。

则这道题转换成了求0或1的矩阵/正方形最大面积。

我们可以使用悬线法,这里使用单调栈为以后的学习打个基础。

我们预处理出每个格子最多可以往上延伸多少格子,单调栈维护一下,同时记录它的最远左边界。

显然如果栈没有弹出那么说明这个格子是和前面栈里的元素是割裂开的,于是正常处理。

否则不断弹出栈顶元素并且更新,同时更新我们即将加入的元素的最远左边界(就是最晚弹出的那个元素的最远左边界啦)

#include<cstdio>
#include<queue>
#include<cctype>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int N=2010;
inline int read(){int x;scanf("%d",&x);return x;}
int n,m,ans1,ans2,mp[N][N],nw[N][N];
int q[N][2];
void init(int k){
    for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
        if(mp[i][j]==k)nw[i][j]=nw[i-1][j]+1;
        else nw[i][j]=0;
    }
    }
}
void suan(int x){
    int t,l=0;
    for(int i=1;i<=m+1;i++){
    t=i;
    while(q[l][0]>=nw[x][i]&&l){
        int len=min(i-q[l][1],q[l][0]);
        ans1=max(ans1,len*len);
        ans2=max(ans2,(i-q[l][1])*q[l][0]);
        t=q[l--][1];
    }
    q[++l][0]=nw[x][i];q[l][1]=t;
    }
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
        int a=read();
        if(((i&1)==(j&1)&&a)||((i&1)!=(j&1)&&!a))mp[i][j]=1;
    }
    }
    for(int i=0;i<=1;i++){
    init(i);
    for(int j=1;j<=n;j++)suan(j);
    }
    printf("%d\n%d\n",ans1,ans2);
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

原文地址:https://www.cnblogs.com/luyouqi233/p/8524696.html

时间: 2024-10-28 20:23:45

BZOJ1057:[ZJOI2007]棋盘制作——题解的相关文章

bzoj1057: [ZJOI2007]棋盘制作

一直想不通为什么最后要push(i+1,0)然后发现没有被pop掉的肯定没有被计算过.所以最后是来计算这些的... #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>

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

1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 1848  Solved: 936 [Submit][Status][Discuss] Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳.而我们的主人公小Q,正是国际象棋的狂热爱好者.作为一个顶尖高手,他已

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

Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳.而我们的主人公小Q, 正是国际象棋的狂热爱好者.作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W决定 将棋盘扩大以适应他们的新规则.小Q找到了一张由N*M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种 颜色之一.小Q想在这种纸中裁减一部分作为新棋盘,当然,他希望这个

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

题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的主人公小Q,正是国际象棋的狂热爱好者.作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W决定将棋盘扩大以适应他们的新规则. 小Q找到了一张由N*M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种颜色之一.小Q想在这种纸中裁减一部分作为新棋盘,当然,他希望这个棋盘尽可能的大.

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

题目要求纵横坐标和奇偶性不同的点取值不同,于是我们把纵横坐标和奇偶性为1的点和0的点分别取反,就变成经典的最大全1子矩阵问题了,用悬线法解决. #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> using namespace std; const int maxn=2010,inf=1e9; int n,m,ans1,ans2; int h[maxn],mp[max

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

既然要求最大01子矩阵,那么把应该为0的位置上的数取反,这样就变成求最大子矩阵 最大子矩阵可以用单调栈 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #define maxn 2005 5 using namespace std; 6 int n,m,map[maxn][maxn],ans1,ans2,l[maxn],r[maxn],d[maxn],t; 7 8 int main(){

BZOJ 1057: [ZJOI2007]棋盘制作 悬线法求最大子矩阵+dp

1057: [ZJOI2007]棋盘制作 Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳.而我们的主人公小Q,正是国际象棋的狂热爱好者.作为一个顶尖高手,他已不满足于普通的棋盘与规则,于是他跟他的好朋友小W决定将棋盘扩大以适应他们的新规则.小Q找到了一张由N*M个正方形的格子组成的矩形纸片,每个格子被涂有黑白两种颜色之一.小Q想在这种纸中裁减

【BZOJ 1057】 [ZJOI2007]棋盘制作

1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 1496  Solved: 753 [Submit][Status] Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳.而我们的主人公小Q,正是国际象棋的狂热爱好者.作为一个顶尖高手,他已不满足于普通的棋盘

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)) + 1 (假如(i, j)和右边和下边不冲突) 第二问就是经典的悬线法解决最大子矩阵了, 维护悬线H[i][j], 左边右边延伸的最长距离.先一行一行求出这一行的L, R, 然后再从上往下扫, 维护H, L, R 写完我才发现我脑残了...最大的正方形一定是在最大子矩阵里面啊...所以其实不用dp.