题目链接:传送门

题目:

  1. 题目描述
  2.  
  3. 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小。
  4. 输入输出格式
  5. 输入格式:
  6.  
  7. 第一行为3个整数,分别表示a,b,n的值
  8.  
  9. 第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。
  10.  
  11. 输出格式:
  12.  
  13. 仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值。
  14.  
  15. 输入输出样例
  16. 输入样例#:
  17.  
  18. 输出样例#:
  19.  
  20. 说明
  21.  
  22. 问题规模
  23.  
  24. ()矩阵中的所有数都不超过1,,,
  25.  
  26. ()%的数据2<=a,b<=,n<=a,n<=b,n<=
  27.  
  28. ()%的数据2<=a,b<=,n<=a,n<=b,n<=

思路:

用2*b个单调队列维护:

  每长度为n的最大值和最小值;

再用2个单调队列维护:

  更新到当前为止,行数为n的最大值的最大值,和最小值的最小值。

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. const int MAX_N = 1e3 + ;
  5. const int INF = 0x3f3f3f3f;
  6.  
  7. struct Node{
  8. int val, ind;
  9. Node(int v = , int i = ) : val(v), ind(i) {}
  10. }querow[MAX_N], quecol[MAX_N][MAX_N], querow2[MAX_N], quecol2[MAX_N][MAX_N];
  11.  
  12. int a, b, n;
  13. int headrow, tailrow, headcol[MAX_N], tailcol[MAX_N];
  14. int headrow2, tailrow2, headcol2[MAX_N], tailcol2[MAX_N];
  15. int mat[MAX_N][MAX_N];
  16.  
  17. int main()
  18. {
  19. cin >> a >> b >> n;
  20. int ans = INF;
  21. for (int i = ; i <= a; i++)
  22. for (int j = ; j <= b; j++)
  23. scanf("%d", &mat[i][j]);
  24. for (int i = ; i <= a; i++)
  25. headcol[i] = , tailcol[i] = , headcol2[i] = , tailcol2[i] = ;
  26. for (int i = ; i <= a; i++) {
  27. headrow = headrow2 = ;
  28. tailrow = tailrow2 = ;
  29. for (int j = ; j <= b; j++) {
  30. while (headcol[j] <= tailcol[j] && quecol[j][tailcol[j]].val <= mat[i][j])
  31. tailcol[j]--;
  32. quecol[j][++tailcol[j]] = Node(mat[i][j], i);
  33. while (headcol[j] <= tailcol[j] && quecol[j][headcol[j]].ind <= i-n)
  34. headcol[j]++;
  35. Node cur = quecol[j][headcol[j]];
  36. while (headrow <= tailrow && querow[tailrow].val <= cur.val)
  37. tailrow--;
  38. querow[++tailrow] = Node(cur.val, j);
  39. while (headrow <= tailrow && querow[headrow].ind <= j-n)
  40. headrow++;
  41. Node _max = querow[headrow];
  42.  
  43. while (headcol2[j] <= tailcol2[j] && quecol2[j][tailcol2[j]].val >= mat[i][j])
  44. tailcol2[j]--;
  45. quecol2[j][++tailcol2[j]] = Node(mat[i][j], i);
  46. while (headcol2[j] <= tailcol2[j] && quecol2[j][headcol2[j]].ind <= i-n)
  47. headcol2[j]++;
  48. Node cur2 = quecol2[j][headcol2[j]];
  49. while (headrow2 <= tailrow2 && querow2[tailrow2].val >= cur2.val)
  50. tailrow2--;
  51. querow2[++tailrow2] = Node(cur2.val, j);
  52. while (headrow2 <= tailrow2 && querow2[headrow2].ind <= j-n)
  53. headrow2++;
  54. Node _min = querow2[headrow2];
  55. if (i >= n && j >= n)
  56. ans = min(ans, _max.val - _min.val);
  57. }
  58. }
  59. cout << ans << endl;
  60. return ;
  61. }

P2216 [HAOI2007]理想的正方形(dp+单调队列优化)的更多相关文章

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

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

  2. [P2216] [HAOI2007]理想的正方形 「单调队列」

    思路:用单调队列分别维护行与列. 具体实现方法:是先用单调队列对每一行的值维护,并将a[][]每个区间的最大值,最小值分别存在X[][]和x[][]中. 那么X[][]与x[][]所存储的分别是1×n ...

  3. Luogu 2216 [HAOI2007]理想的正方形 (单调队列优化)

    题意: 给出一个 N×M 的矩阵,以及一个数值 K ,求在给定的矩阵中取出一个 K×K 的矩阵其中最大值减去最小值的最小值. 细节: 没有细节来发暴力走天下,20分也是分啊~~~ QAQ. 分析: 感 ...

  4. 【BZOJ1047】[HAOI2007]理想的正方形(单调队列,动态规划)

    [BZOJ1047][HAOI2007]理想的正方形(单调队列,动态规划) 题面 BZOJ 洛谷 题解 直接一个单调队列维护一下没给点和它前面的\(n\)个位置的最大值,再用一次单调队列维护连续\(n ...

  5. [BZOJ 1047] [HAOI2007] 理想的正方形 【单调队列】

    题目链接:BZOJ - 1047 题目分析 使用单调队列在 O(n^2) 的时间内求出每个 n * n 正方形的最大值,最小值.然后就可以直接统计答案了. 横向有 a 个单调队列(代码中是 Q[1] ...

  6. 【BZOJ】1047: [HAOI2007]理想的正方形(单调队列/~二维rmq+树状数组套树状数组)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1047 树状数组套树状数组真心没用QAQ....首先它不能修改..而不修改的可以用单调队列做掉,而且更 ...

  7. bzoj 1047: [HAOI2007]理想的正方形【单调队列】

    没有复杂结构甚至不长但是写起来就很想死的代码类型 原理非常简单,就是用先用单调队列处理出mn1[i][j]表示i行的j到j+k-1列的最小值,mx1[i][j]表示i行的j到j+k-1列的最大值 然后 ...

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

    题目链接:P2216 [HAOI2007]理想的正方形 题目描述 有一个 \(a\times b\)的整数组成的矩阵,现请你从中找出一个 \(n\times n\)的正方形区域,使得该区域所有数中的最 ...

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

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

  10. [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)

    DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...

随机推荐

  1. spring事务管理(详解和实例)

    原文地址: 参考地址:https://blog.csdn.net/yuanlaishini2010/article/details/45792069 写这篇博客之前我首先读了<Spring in ...

  2. Zookeeper面试题

    Zookeeper是什么框架 分布式的.开源的分布式应用程序协调服务,原本是Hadoop.HBase的一个重要组件.它为分布式应用提供一致性服务的软件,包括:配置维护.域名服务.分布式同步.组服务等. ...

  3. react router @4 和 vue路由 详解(六)vue怎么通过路由传参?

    完整版:https://www.cnblogs.com/yangyangxxb/p/10066650.html 8.vue怎么通过路由传参? a.通配符传参数 //在定义路由的时候 { path: ' ...

  4. 【基础】火狐和谷歌在Selenium3.0上的启动(二)

    参考地址:http://www.cnblogs.com/fnng/p/5932224.html https://github.com/mozilla/geckodriver [火狐浏览器] 火狐浏览器 ...

  5. HTML编辑笔记4

    1.CSS(层叠样式表) 2.CSS语法 选择器{ 属性名1:属性值1: 属性名2:属性值2: } 3.引用CSS的三种方式 第一种:行内样式 例:<a style="color:re ...

  6. SpringBoot 上传、下载(四)

    工程目录结构 完整代码: 1.pom.xml 首先当然是添加依赖,用到thymeleaf模板渲染html页面 <project xmlns="http://maven.apache.o ...

  7. 图解前序遍历线索化二叉树,前序线索二叉树遍历,C\C++描述

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  8. 深入理解java虚拟机---jdk8新特性(二)

    1.jdk8新特性 1.新特性 2.lambda函数表达式的作用 A: 替换内部类 B:对集合的操作并行化

  9. easyui再学习的一部分代码

    <%-- Created by IntelliJ IDEA. User: zhen Date: // Time: : To change this template use File | Set ...

  10. mysql修改lower_case_table_names产生的问题

    1.参数含义: lower_case_table_names: 此参数不可以动态修改,必须重启数据库 lower_case_table_names = 1 表名存储在磁盘是小写的,但是比较的时候是不区 ...