思路:悬线法\(or\)单调栈

提交:2次

错因:正方形面积取错了\(QwQ\)

题解:

悬线法

讲解:王知昆\(dalao\)的\(PPT\)

详见代码:

#include<cstdio>
#include<iostream>
#define ull unsigned long long
#define ll long long
#define R register int
using namespace std;
#define pause (for(R i=1;i<=10000000000;++i))
#define In freopen("NOIPAK++.in","r",stdin)
#define Out freopen("out.out","w",stdout)
namespace Fread {
static char B[1<<15],*S=B,*D=B;
#ifndef JACK
#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
#endif
inline int g() {
R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
if(ch==EOF) return EOF; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
} inline bool isempty(const char& ch) {return (ch<=36||ch>=127);}
inline void gs(char* s) {
register char ch; while(isempty(ch=getchar()));
do *s++=ch; while(!isempty(ch=getchar()));
}
} using Fread::g; using Fread::gs;
namespace Luitaryi {
const int N=4010;
int n,m,a[N][N],l[N][N],r[N][N],h[N][N],S1,S2;
inline void main() {
n=g(),m=g();
for(R i=1;i<=n;++i) for(R j=1;j<=m;++j) a[i][j]=g(),l[i][j]=r[i][j]=j,h[i][j]=1;//刚开始令悬线长度为1,左右边界都是本身。
for(R i=1;i<=n;++i) for(R j=2;j<=m;++j) if(a[i][j]!=a[i][j-1]) l[i][j]=l[i][j-1];//在悬线长度为1时,尝试扩大左右边界
for(R i=1;i<=n;++i) for(R j=m-1; j;--j) if(a[i][j]!=a[i][j+1]) r[i][j]=r[i][j+1];
for(R i=1;i<=n;++i) for(R j=1;j<=m;++j) {
if(i>1) if(a[i][j]!=a[i-1][j]) {//若颜色不相等,尝试合并悬线。
l[i][j]=max(l[i][j],l[i-1][j]),//左端点往大取
r[i][j]=min(r[i][j],r[i-1][j]),//右端点往小取
h[i][j]=h[i-1][j]+1;//悬线长度+1
} R a=r[i][j]-l[i][j]+1,b=min(a,h[i][j]);
S1=max(S1,b*b),S2=max(S2,a*h[i][j]);//计算面积
} printf("%d\n%d\n",S1,S2);
}
}
signed main() {
Luitaryi::main(); return 0;
}

单调栈

其实单调栈我没有写,但是教练给的标签是单调栈。。。然后稍微想了想又看了看题解\(QwQ\)

以下引用自@luogu.org lzoi_lhy

从第一行到第n行扫一遍,维护h数组表示从当前格子往上能延伸到的黑白相间的线段(有一条边长为1的矩形)的最长长度

我们可将当前行分为若干条线段,满足每条线段是最长的黑白相间的线段(不能再向左右延伸)

对于每条线段,结合h数组,我们不难发现我们得到了一排高矮不一的长条状的矩形

是不是很熟悉?用单调栈扫一遍即可

如果遇到颜色与上一个相同的格子,就把整个栈弹出来

注意正方形可以在数矩形的时候顺便数出来

#include<cstdio>
#include<iostream>
#include<cstring>
#define X (h[stack[top]])//矩形的宽
#define Y (cur-stack[top-1]-1)//矩形的长
#define Z (min(X,Y))//正方形的边长
using namespace std;
int n,m,top,cur,ans1,ans2,stack[2010],map[2010][2010],h[2010];
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j) scanf("%d",&map[i][j]);
for (int j=1;j<=n;++j){
for (int i=1;i<=m;++i)
if (j>1&&map[j][i]!=map[j-1][i]) ++h[i];
else h[i]=1;
cur=1;
while (cur<=m){
stack[0]=cur-1;stack[top=1]=cur++;
while (cur<=m&&(map[j][cur]!=map[j][cur-1])){
while (top&&h[stack[top]]>h[cur])
ans1=max(ans1,Z*Z),ans2=max(ans2,X*Y),--top;
stack[++top]=cur++;
}
while (top) ans1=max(ans1,Z*Z),ans2=max(ans2,X*Y),--top;
}
}
printf("%d\n%d\n",ans1,ans2);
return 0;
}

2019.07.22

P1169 [ZJOI2007]棋盘制作 悬线法or单调栈的更多相关文章

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

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

  2. 洛谷P1169 [ZJOI2007]棋盘制作 悬线法 动态规划

    P1169 [ZJOI2007]棋盘制作 (逼着自己做DP 题意: 给定一个包含0,1的矩阵,求出一个面积最大的正方形矩阵和长方形矩阵,要求矩阵中相邻两个的值不同. 思路: 悬线法. 用途: 解决给定 ...

  3. P1169 [ZJOI2007]棋盘制作[悬线法/二维dp]

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

  4. P1169 [ZJOI2007]棋盘制作——悬线法

    ---恢复内容开始--- 给你一个矩阵,选出最大的棋盘,棋盘的要求是黑白相间(01不能相邻),求出最大的正方形和矩形棋盘的面积: 数据n,m<=2000; 这个一看就可能是n2DP,但是写不出. ...

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

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

  6. [ZJOI2007]棋盘制作 悬线法dp 求限制下的最大子矩阵

    https://www.luogu.org/problemnew/show/P1169 第一次听说到这种dp的名称叫做悬线法,听起来好厉害 题意是求一个矩阵内的最大01交错子矩阵,开始想的是dp[20 ...

  7. [P1169] 棋盘制作 &悬线法学习笔记

    学习笔记 悬线法 最大子矩阵问题: 在一个给定的矩形中有一些障碍点,找出内部不包含障碍点的,边与整个矩形平行或重合的最大子矩形. 极大子矩型:无法再向外拓展的有效子矩形 最大子矩型:最大的一个有效子矩 ...

  8. 【ZJOI2007】棋盘制作 - 悬线法

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

  9. 【BZOJ-3039&1057】玉蟾宫&棋盘制作 悬线法

    3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 753  Solved: 444[Submit][Status][Discuss] D ...

随机推荐

  1. Winscp隧道实现-跳板机/跨机连接

    隧道用的是公网ip,登陆用的是私网ip 一张图应该就能看懂,后续用到新的功能继续编辑

  2. go hello world第一个程序

    main 函数所在的包名必须使用main import "fmt"  导入包fmt  fmt包包含了Println方法的定义 func main() 程序运行入口方法和c语言相似 ...

  3. (六)Hibernate的增删改查操作(3)

    一.在Hibernate中使用原生SQL语句 sql语句面向的是数据库,所以sql语句中对应的不再是bean了,比如sql="select * from user"   在hql中 ...

  4. params关键字应用

    params 是C#中的可变参数, params主要的用处是在给函数传参数的时候用,就是当函数的参数不固定的时候.  关于参数数组,需掌握以下几点. (1)在方法声明中的 params 关键字之后不允 ...

  5. sublimeText3汉化安装教程 附注册码

    sublimeText3汉化安装教程 sublimeText3 很不错,前面几天下了vscore学习Node.js,感觉有点懵,今天下载sublimeText3,遇到的一些小问题,在这里说说: 百度云 ...

  6. 【web】使用ionic搭建移动端项目 icon-radio 标签在ios下全部选中的问题

    这块css 导致的问题 .disable-pointer-events { pointer-events: none; }

  7. IE6图片透明问题

    网上很多解决IE6下png透明问题的方案,但是经本人实践,有的时候有用,有的时候并不能解决自己的问题.当是后者的时候,想到另外一种办法,就是当在IE6.IE7下使用gif图片,自己在测试的时候,如果g ...

  8. mycat 报错 java.lang.OutOfMemoryError: Java heap space

    今天排查mysql的错误日志发现  wrapper.log  中有如下错误日志 INFO   | jvm 1    | 2019/10/20 12:52:31 | java.lang.OutOfMem ...

  9. Node中的net模块提供的前端通信

    Node中的net模块提供的前端通信 客户端 业务: 客户端现在要在终端输入内容,然后回车发送内容给服务器 解决: Node中提供了一个叫做 readline 的 模块用于读取命令行内容 [ 单行读取 ...

  10. # 机器学习算法总结-第九天(XGboost)