BZOJ 1057 ZJOI2007 棋盘制作 单调栈

题目大意:给定一个黑白两色的矩阵,求最大的黑白相间的子正方形和子矩阵

将奇数位置的点反色,然后就是求纯色的最大子正方形和子矩阵

将矩阵一层层剖分,每层上方是一段类似于▆▃▇▂▉的东西,用单调栈跑出每个点向左向右能拓展到的最大距离,更新答案即可

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 2020
using namespace std;
int m,n,ans1,ans2;
int map[M][M],a[M];
void Calculate()
{
	static int stack[M],top;
	static int left[M],right[M];
	int i;top=0;
	for(i=1;i<=n+1;i++)
	{
		while( top && a[i]<a[stack[top]] )
		{
			right[stack[top]]=i;
			stack[top--]=0;
		}
		stack[++top]=i;
	}
	top=0;
	for(i=n;~i;i--)
	{
		while( top && a[i]<a[stack[top]] )
		{
			left[stack[top]]=i;
			stack[top--]=0;
		}
		stack[++top]=i;
	}
	for(i=1;i<=n;i++)
	{
		int len=right[i]-left[i]-1;
		ans1=max(ans1,min(len,a[i])*min(len,a[i]) );
		ans2=max(ans2,len*a[i]);
	}
}
int main()
{
	int i,j;
	cin>>m>>n;
	for(i=1;i<=m;i++)
		for(j=1;j<=n;j++)
		{
			scanf("%d",&map[i][j]);
			if(i+j&1) map[i][j]^=1;
		}
	for(i=1;i<=m;i++)
	{
		for(j=1;j<=n;j++)
			a[j]=(map[i][j]?0:a[j]+1);
		Calculate();
	}
	memset(a,0,sizeof a);
	for(i=1;i<=m;i++)
		for(j=1;j<=n;j++)
			map[i][j]^=1;
	for(i=1;i<=m;i++)
	{
		for(j=1;j<=n;j++)
			a[j]=(map[i][j]?0:a[j]+1);
		Calculate();
	}
	cout<<ans1<<endl<<ans2<<endl;
	return 0;
}
时间: 2024-11-08 20:16:49

BZOJ 1057 ZJOI2007 棋盘制作 单调栈的相关文章

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

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

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

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

BZOJ 1057: [ZJOI2007]棋盘制作

Decsription 给你一个矩阵,求最大了 01相间 的矩阵. Sol DP+悬线法. 这是一个论文啊 <浅谈用极大化思想解决最大子矩形问题>--王知昆. 枚举每一根悬线,记录最左/右/上能到达的点,统计答案. Code /************************************************************** Problem: 1057 User: BeiYu Language: C++ Result: Accepted Time:1384 ms Me

BZOJ 1057 [ZJOI2007]棋盘制作 最大子矩阵

题意:链接 方法:最大子矩阵 解析: 这题很水- - 显然最大子正方形是在最大子矩阵之中的,所以没有什么卵区别.极大子矩阵的较小边长即为极大子正方形的边长,最长边长的极大子正方形即为最大子正方形. 然后呢,这题有个小小的区别,就是他要黑白相间的?- - 有什么区别呢?并没有,只需要求le,ri的时候改一下判断就OK了,非常的水. 代码: #include <cstdio> #include <cstring> #include <iostream> #include &

1057: [ZJOI2007]棋盘制作

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

【BZOJ 1057】 [ZJOI2007]棋盘制作

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

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,正是国际象棋的狂热爱好者.作为一个顶尖高手,他已