题意: 给一个矩阵,给出行列和每个数,再给出一个N,求出所有N*N的子矩阵中最大值最小值之差的最小值
解析: 暴力枚举肯定不行,这题可以用二维单调队列做,把同一行的连续N个点缩成一个点保存最大最小值预处理
,用单调队列即可实现,再对整个矩阵进行枚举,再用一次单调队列。

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<vector>
  5. #include<cmath>
  6. using namespace std;
  7. const int INF=1e9+;
  8. const int maxn=;
  9. int row,col,N;
  10. int A[maxn][maxn];
  11. int Min[maxn][maxn],Max[maxn][maxn];
  12. int q1[maxn],q2[maxn];
  13. int f1,f2,r1,r2;
  14. void init() //预处理
  15. {
  16. for(int i=;i<=row;i++)
  17. {
  18. f1=,r1=;
  19. f2=,r2=;
  20. for(int j=;j<N;j++)
  21. {
  22. while(r1>=f1&&A[i][q1[r1]]>=A[i][j]) r1--;
  23. q1[++r1]=j;
  24. while(r2>=f2&&A[i][q2[r2]]<=A[i][j]) r2--;
  25. q2[++r2]=j;
  26. }
  27. for(int j=N;j<=col;j++)
  28. {
  29. while(r1>=f1&&A[i][q1[r1]]>=A[i][j]) r1--;
  30. q1[++r1]=j;
  31. while(q1[f1]+N<=j) f1++;
  32. Min[i][j-N+]=A[i][q1[f1]]; //缩点后的最小值
  33.  
  34. while(r2>=f2&&A[i][q2[r2]]<=A[i][j]) r2--;
  35. q2[++r2]=j;
  36. while(q2[f2]+N<=j) f2++;
  37. Max[i][j-N+]=A[i][q2[f2]]; //缩点后的最大值
  38. }
  39. }
  40. }
  41. int solve()
  42. {
  43. int ret=INF;
  44. for(int j=;j+N-<=col;j++) //对同一列进行枚举
  45. {
  46. f1=,r1=;
  47. f2=,r2=;
  48. int minv=INF,maxv=-INF;
  49. for(int i=;i<N;i++)
  50. {
  51. while(r1>=f1&&Min[q1[r1]][j]>=Min[i][j]) r1--;
  52. q1[++r1]=i;
  53. while(r2>=f2&&Max[q2[r2]][j]<=Max[i][j]) r2--;
  54. q2[++r2]=i;
  55. }
  56. for(int i=N;i<=row;i++)
  57. {
  58. while(r1>=f1&&Min[q1[r1]][j]>=Min[i][j]) r1--;
  59. q1[++r1]=i;
  60. while(q1[f1]+N<=i) f1++;
  61. minv=Min[q1[f1]][j];
  62. while(r2>=f2&&Max[q2[r2]][j]<=Max[i][j]) r2--;
  63. q2[++r2]=i;
  64. while(q2[f2]+N<=i) f2++;
  65. maxv=Max[q2[f2]][j];
  66. ret=min(ret,maxv-minv);
  67. }
  68. }
  69. return ret;
  70. }
  71. int main()
  72. {
  73. scanf("%d%d%d",&row,&col,&N);
  74. for(int i=;i<=row;i++)
  75. for(int j=;j<=col;j++) scanf("%d",&A[i][j]);
  76. init();
  77. printf("%d\n",solve());
  78. return ;
  79. }

bzoj1047-理想的正方形(二维单调队列)的更多相关文章

  1. [BZOJ1047][HAOI2007]理想的正方形 二维单调队列

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1047 我们对每矩阵的一列维护一个大小为$n$的单调队列,队中元素为矩阵中元素.然后扫描每一 ...

  2. bzoj1047 [HAOI2007]理想的正方形——二维单调队列

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1047 就是先对行做一遍单调队列,再对那个结果按列做一遍单调队列即可. 代码如下: #incl ...

  3. 【二维单调队列】BZOJ1047-[HAOI2007]理想的正方形

    [题目大意] 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. [思路] 裸的二维单调队列.二维单调队列的思路其实很简单: (1)对于每 ...

  4. 洛谷 P2216 [HAOI2007]理想的正方形 || 二维RMQ的单调队列

    题目 这个题的算法核心就是求出以i,j为左上角,边长为n的矩阵中最小值和最大值.最小和最大值的求法类似. 单调队列做法: 以最小值为例: q1[i][j]表示第i行上,从j列开始的n列的最小值.$q1 ...

  5. [luoguP2216] [HAOI2007]理想的正方形(二维单调队列)

    传送门 1.先弄个单调队列求出每一行的区间为n的最大值最小值. 2.然后再搞个单调队列求1所求出的结果的区间为n的最大值最小值 3.最后扫一遍就行 懒得画图,自己体会吧. ——代码 #include ...

  6. BZOJ1047[HAOI2007]理想的正方形——二维ST表

    题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非 ...

  7. 【bzoj1047】[HAOI2007]理想的正方形 二维RMQ

    题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非 ...

  8. [HAOI2007]理想的正方形 st表 || 单调队列

    ~~~题面~~~ 题解: 因为数据范围不大,而且题目要求的是正方形,所以这道题有2种解法. 1,st表. 这种解法暴力好写好理解,但是较慢.我们设st[i][j][k]表示以(i, j)为左端点,向下 ...

  9. BZOJ 1047 二维单调队列

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1047 题意:见中文题面 思路:该题是求二维的子矩阵的最大值与最小值的差值尽量小.所以可以考 ...

随机推荐

  1. <Win32_9>有意思的程序——抓取屏幕

    Win32学了一段时间了,跟着杨老师的脚步,准备学习MFC,因此最近几天在复习C++,于是发现有将近一周没写博文了…… 今天来写一个较为简单.但是比较有意思的东西 不知大家在理发店理发的时候注意到一个 ...

  2. Storm drpc学习

    示例代码: package com.lky.test; import org.apache.commons.logging.Log; import org.apache.commons.logging ...

  3. spring mvc json 返回乱码问题解决(vestion:3.x.x)

    本文是转载文章,感觉比较好,如有侵权,请联系本人,我将及时删除. 原文网址:<spring mvc json 返回乱码问题解决(vestion:3.x.x)> 工程中用springmvc返 ...

  4. JS浏览器对象-window对象

    代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title ...

  5. Linux下的bc计算器

    bc = basic calculator scale:设置精度,默认为0 obase:设置输出进制,默认为10 ibase:设置输入进制,默认为10 原文:http://www.linuxidc.c ...

  6. (转)苹果推送通知服务教程 Apple Push Notification Services Tutorial

    本文译自http://www.raywenderlich.com/.原文由iOS教程团队 Matthijs Hollemans 撰写,经原网站管理员授权本博翻译. 在iOS系统,考虑到手机电池电量,应 ...

  7. linux增大交换分区

    进来在批量搭建环境,遇到搭建完环境之后发现swap忘记的情况,后来百度了下,发现了下面的方法,网上可能存在好多相应的帖子说这个事情也比较简单,以下是自己实践的结果,分享给大家. 1.查看现有memor ...

  8. c标签的使用方法

    1. c:forEach <c:forEach items="> 注意varStatus相当于for循环计数器,从1开始,用${varStatus.count}获得计数器的值.而 ...

  9. 自定义标签(JSTL)

    自定义标签的步骤: 1.确定需求,如:用<my:date/>输出当前时间 2.编写Java类:需要实现实现接口javax.servlet.jsp.tagext.JspTag 具体的接口为: ...

  10. myeclipse笔记(3):导入的项目切换jdk版本

    有时候,从外面导入的javaweb项目会访问不了,这个时候改变jdk版本就是其中解决的方法之一. 右键点击项目 --> bulid path --> configure​ ​​​ 选择需要 ...