点此看题面

大致题意: 给你一个\(N*M\)的\(01\)矩阵,要求你分别求出最大的\(01\)相间的正方形和矩形(矩形也可以是正方形),并输出其面积。

题解

这题第一眼看去没什么思路,仔细想想,能发现这道题其实是一道单调栈的运用题。

我们可以先对矩阵上的每一个元素进行预处理,求出以其为底的最长的 \(01\)柱

然后对矩形(正方形)的下界进行枚举,即枚举每一行作为矩形(正方形)的下边。

此时,我们发现,只要使连续的01柱连续距离和这些\(01\)柱中最短的\(01\)柱的高度的乘积最大,就可以求出最大的矩形(最大的正方形同理)。

那么,我们该如何求出每一种情况呢?这时候就要用到单调栈

我们可以建立一个严格递增的单调栈,每当单调栈栈顶的元素被弹出,我们就求出以它为右边界的最大矩阵。可以保证这样不会遗漏正确答案。

代码

  1. #include<bits/stdc++.h>
  2. #define N 2000
  3. using namespace std;
  4. int n,m,ans1,ans2,Stack[N+5],Val[N+5],a[N+5][N+5],h[N+5][N+5];
  5. inline char tc()
  6. {
  7. static char ff[100000],*A=ff,*B=ff;
  8. return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
  9. }
  10. inline void read(int &x)
  11. {
  12. x=0;int f=1;char ch;
  13. while(!isdigit(ch=tc())) if(ch=='-') f=-1;
  14. while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
  15. x*=f;
  16. }
  17. inline void write(int x)
  18. {
  19. if(x<0) putchar('-'),x=-x;
  20. if(x>9) write(x/10);
  21. putchar(x%10+'0');
  22. }
  23. int main()
  24. {
  25. register int i,j;
  26. for(read(n),read(m),i=1;i<=n;++i)
  27. for(j=1;j<=m;++j)
  28. read(a[i][j]);
  29. for(i=1;i<=m;++i) h[1][i]=1;
  30. for(i=2;i<=n;++i)//预处理出以每个元素为底部的最长01柱
  31. for(j=1;j<=m;++j)
  32. h[i][j]=a[i-1][j]^a[i][j]?h[i-1][j]+1:1;//若其与上方的元素不同,则其可以与其上方元素构成一个01柱,否则以当前元素作为一个新的01柱
  33. for(i=1;i<=n;++i)//枚举矩形的下界
  34. {
  35. int top,num;//top记录栈顶,num记录当前元素最大能达到的距离
  36. a[i][m+1]=a[i][m]^1,h[i][m+1]=0,Stack[top=1]=1,Val[1]=h[i][1];
  37. for(j=2;j<=m+1;++j)
  38. {
  39. num=j;
  40. if(!(a[i][j]^a[i][j-1]))//比较当前元素与前面的元素的异同,若相同,则清空栈并更新ans
  41. {
  42. while(top)
  43. {
  44. ans1=max(ans1,min(Val[top],j-Stack[top]));//先记录正方形的边长,最后再将其平方
  45. ans2=max(ans2,Val[top]*(j-Stack[top]));
  46. --top;
  47. }
  48. }
  49. while(top&&h[i][j]<=Val[top])//由于要严格满足单调递增,所以要将栈中大于等于当前元素的元素弹出
  50. {
  51. ans1=max(ans1,min(Val[top],j-Stack[top]));
  52. ans2=max(ans2,Val[top]*(j-Stack[top]));
  53. num=Stack[top--];
  54. }
  55. Stack[++top]=num,Val[top]=h[i][j];//将当前元素加入栈
  56. }
  57. }
  58. return write(ans1*ans1),putchar('\n'),write(ans2),0;
  59. }

【BZOJ1057】[ZJOI2007] 棋盘制作(单调栈的运用)的更多相关文章

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

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

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

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

  3. [ZJOI2007]棋盘制作 (单调栈)

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

  4. [ZJOI2007]棋盘制作 (单调栈,动态规划)

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

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

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

  6. BZOJ1057 [ZJOI2007]棋盘制作 【最大同色矩形】

    1057: [ZJOI2007]棋盘制作 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 3248  Solved: 1636 [Submit][St ...

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

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

  8. BZOJ1057 [ZJOI2007]棋盘制作

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

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

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

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

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

随机推荐

  1. elasticsearch 基本介绍

    1. Elasticsearch的适用场景: (1)类似百度百科的全文检索,高亮,搜索推荐(2)新闻类的搜索,用户行为日志(点击,浏览,收藏,评论)+社交网络数据(对某某新闻的相关看法),数据分析,给 ...

  2. [Xcode 实际操作]四、常用控件-(16)为MKMapView指定地理坐标

    目录:[Swift]Xcode实际操作 本文将演示如何自定义地图视图的的地理坐标 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit //首先 ...

  3. 解决Win10中vmware运行特别慢问题

    1.关闭防火墙:win+S打开搜索框,输入防火墙,选择windowsDefender防火墙 ,如图: 2.启用或关闭防火墙,如图: 3.关闭防火墙,两个选项都关闭,如图: 4.打开VMware,如果速 ...

  4. EIGRP-3-EIGRP的多参数度量

    带宽度量参数本身无法区分10Gbit/s及更高速率的接口.对1Gbit/s接口,默认延迟度量参数已设置为最低值1(10微妙).而且EIGRP承载的是经过换算的参数,每台路由器需要将其换算回再计算新开销 ...

  5. LeetCode初级算法(其他篇)

    目录 缺失数字 位1的个数 颠倒二进制位 有效的括号 汉明距离 帕斯卡三角形 缺失数字 最初的想法是将0到n全部加起来,再减去输入的数字之和,那么差如果非零的话就是我们所需要的数字.但是一想,可能会发 ...

  6. Leetcode初级算法(排序和搜索+数学篇)

    合并两个有序数组 开始的时候将这道题理解错了,发现几个奇怪的测试案例后才明白这道题什么意思.本来的想法就是把nums2全部放到num1里面,然后删除重复元素.排序一下,就有了下面的代码: class ...

  7. Migration-添加表

    public partial class _111111 : DbMigration { public override void Up() { CreateTable( "dbo.Asse ...

  8. 洛谷2747(不相交路线、dp)

    要点 反思:以前是在紫书上做过的-- \(dp[i][j]\)是从1引两条路到达i.j的最大值 为了不相交,则\(dp[i][i]\)都是非法的,不转移它,也不用它转移 #include <cs ...

  9. python学习笔记(一)——关于正则表达式的学习小结

    python中提供了re这个模块提供对正则表达式的支持. 一.正则表达式常用到的一些语法(并非全部): . 匹配任意单个字符 [...] 匹配单个字符集 \w 匹配单词字符,即[a-zA-Z0-9] ...

  10. Jenkins +Maven+Tomcat+SVN +Apache项目持续集成构建

    详解Jenkins +Maven+Tomcat+SVN +Apache项目持续集成 一:前言 1. Jenkins jenkins版本大全http://mirrors.jenkins-ci.org/ ...