二维单调队列

先横向跑一边单调队列,记录下每一行长度为n的区间的最值

在纵向跑一边单调队列,得出结果

注意,mi要初始化为一个足够大的数

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <algorithm>
  5. using namespace std;
  6. int init() {
  7. int rv = 0, fh = 1;
  8. char c = getchar();
  9. while(c < '0' || c > '9') {
  10. if(c == '-') fh = -1;
  11. c = getchar();
  12. }
  13. while(c >= '0' && c <='9') {
  14. rv = (rv<<1) + (rv<<3) + c - '0';
  15. c = getchar();
  16. }
  17. return fh * rv;
  18. }
  19. const int MAXN = 2005;
  20. int num[MAXN][MAXN], ma[MAXN][MAXN], mi[MAXN][MAXN], n, a, b, ans = 0x7fffffff;
  21. struct ddque{
  22. int que[MAXN<<3], head, tail;
  23. void clear(bool opt){
  24. que[0] = opt? 0: 0x7fffffff; //注意这里
  25. head = tail = 0;
  26. }
  27. void insert(int x, bool opt){
  28. if(!opt) {
  29. while(que[tail] > x && tail >= head) tail--;
  30. que[++tail] = x;
  31. }else {
  32. while(que[tail] < x && tail >= head) tail--;
  33. que[++tail] = x;
  34. }
  35. }
  36. void pop(int x){
  37. if(que[head] == x) head++;
  38. }
  39. int query(){
  40. return que[head];
  41. }
  42. }q1, q2;
  43. int main() {
  44. freopen("in.txt", "r", stdin);
  45. memset(mi,0x7f,sizeof(mi));
  46. a = init(); b = init(); n = init();
  47. for(int i = 1 ; i <= a ; i++) {
  48. for(int j = 1 ; j <=b ; j++) {
  49. num[i][j] = init();
  50. }
  51. }
  52. for(int i = 1 ; i <= a ; i++) {
  53. q1.clear(0); q2.clear(1);
  54. for(int j = 1 ; j <= n ; j++) {
  55. q1.insert(num[i][j], 0);
  56. q2.insert(num[i][j], 1);
  57. }
  58. ma[i][n] = q2.query();
  59. mi[i][n] = q1.query();
  60. for(int j = n + 1 ; j <= b ; j++) {
  61. q1.insert(num[i][j], 0);
  62. q2.insert(num[i][j], 1);
  63. q1.pop(num[i][j - n]);
  64. q2.pop(num[i][j - n]);
  65. ma[i][j] = q2.query();
  66. mi[i][j] = q1.query();
  67. }
  68. }
  69. for(int j = n ; j <= b ; j++) {
  70. q1.clear(0); q2.clear(1);
  71. for(int i = 1 ; i <= n ; i++) {
  72. q1.insert(mi[i][j], 0);
  73. q2.insert(ma[i][j], 1);
  74. }
  75. ans = min(ans, q2.query() - q1.query());
  76. for(int i = n + 1 ; i <= a ; i++) {
  77. q1.insert(mi[i][j], 0);
  78. q2.insert(ma[i][j], 1);
  79. q1.pop(mi[i - n][j]);
  80. q2.pop(ma[i - n][j]);
  81. ans = min(ans, q2.query() - q1.query());
  82. }
  83. }
  84. cout<<ans<<endl;
  85. fclose(stdin);
  86. return 0;
  87. }

洛谷 [P2216] 理想的正方形的更多相关文章

  1. 洛谷P2216 理想的正方形(单调队列)

    洛谷P2216 理想的正方形 题目链接 思路: 直接暴力显然不可行,可以发现每一个矩形向右边扩展时是一列一列增加,于是可以想到单调队列,用数组来维护当前每列的最大值.因为行也有限制,所以还要用一个单调 ...

  2. 洛谷P2216 理想的正方形

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

  3. 洛谷P2216: [HAOI2007]理想的正方形 单调队列优化DP

    洛谷P2216 )逼着自己写DP 题意: 给定一个带有数字的矩阵,找出一个大小为n*n的矩阵,这个矩阵中最大值减最小值最小. 思路: 先处理出每一行每个格子到前面n个格子中的最大值和最小值.然后对每一 ...

  4. 洛谷 P2216 [HAOI2007]理想正方形

    洛谷 巨说这是一道单调队列好题,但是我并不是用单调队列做的诶. 如果往最暴力的方向去想,肯定是\(n^3\)的\(dp\)了. \(f[i][j][k]\)代表当前正方形的左上角定点是\((i,j)\ ...

  5. 洛谷 P2216 [HAOI2007]理想的正方形

    P2216 [HAOI2007]理想的正方形 题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一 ...

  6. 【洛谷P2216】[HAOI2007]理想的正方形

    理想的正方形 [题目描述] 一个a*b的矩阵,从中取一个n*n的子矩阵,使所选矩阵中的最大数与最小数的差最小. 思路: 二维的滑动窗口 对于每行:用一个单调队列维护,算出每个长度为n的区间的最大值和最 ...

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

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

  8. 洛谷P2216 HAOI2007 理想的正方形 (单调队列)

    题目就是要求在n*m的矩形中找出一个k*k的正方形(理想正方形),使得这个正方形内最值之差最小(就是要维护最大值和最小值),显然我们可以用单调队列维护. 但是二维平面上单调队列怎么用? 我们先对行处理 ...

  9. 【DP】【单调队列】洛谷 P2216 [HAOI2007]理想的正方形 题解

        算是单调队列的复习吧,不是很难 题目描述 有一个$a\times b$的整数组成的矩阵,现请你从中找出一个$n\times n$的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入 ...

随机推荐

  1. IOS7 Text View 截断的问题解决

    - (void)textViewDidChange:(UITextView *)textView { CGRect line = [textView caretRectForPosition: tex ...

  2. CPP-基础:cout

    C++编程语言互换流中的标准输出流,需要iostream.h支持.读为 "c out". 使用范例 //用户输入的数字由cin保存于变量a中,并通过cout输出. #include ...

  3. 洛谷 P2668 斗地主

    毒瘤题目,搞了三天-- 也没什么好讲的,就是纯搜索,先搜顺子,再搜其他的,最后单张牌和对子的时候,就不要搜索了,直接枚举,不然会T飞掉多么痛的领悟-- 主要还是靠码力 #include<iost ...

  4. ios 团购信息客户端demo(三)

    接上二篇的内容,今天我们就来介绍一下如何将解析出来的数据放入AQGridView中显示出来,因为我们的工程中已经将AQGridView导入了,所以我们在KKFirstViewController中直接 ...

  5. Swift 中 String 与 CChar 数组的转换

    在现阶段Swift的编码中,我们还是有很多场景需要调用一些C函数.在Swift与C的混编中,经常遇到的一个问题就是需要在两者中互相转换字符串.在C语言中,字符串通常是用一个char数组来表示,在Swi ...

  6. centos下nginx安装和配置

    注:此文是根据前辈的博客和自己实际动手总结出来的,不喜勿喷 1.准备工作 Nginx的安装依赖于以下三个包,意思就是在安装Nginx之前首先必须安装一下的三个包,注意安装顺序如下: 1 SSL功能需要 ...

  7. mem之读操作调式总结(跟入栈出栈有关)

    现象: 1.当case比较复杂的时候(含有for循环对mem进行读/写) 发现for循环时总是有汇编指令不执行跳过去了,(其实是汇编不熟和指令太多无法理智分析指令了). 事实是指令是对的,但执行错了( ...

  8. Spring Cloud Stream在同一通道根据消息内容分发不同的消费逻辑

    应用场景 有的时候,我们对于同一通道中的消息处理,会通过判断头信息或者消息内容来做一些差异化处理,比如:可能在消息头信息中带入消息版本号,然后通过if判断来执行不同的处理逻辑,其代码结构可能是这样的: ...

  9. Day07 数据类型(列表,元组,字典,集合)常用操作和内置方法

    数据类型 列表list: 用途:记录多个值(同种属性) 定义方式:[]用逗号分隔开多个任意类型的值 list()造出来的是列表,参数是可迭代对像,也就是可以使用for循环的对像 传入字典,出来的列表元 ...

  10. 数据结构( Pyhon 语言描述 ) — —第10章:树

    树的概览 树是层级式的集合 树中最顶端的节点叫做根 个或多个后继(子节点). 没有子节点的节点叫做叶子节点 拥有子节点的节点叫做内部节点 ,其子节点位于层级1,依次类推.一个空树的层级为 -1 树的术 ...