思路:用单调队列分别维护行与列。

具体实现方法:是先用单调队列对每一行的值维护,并将a[][]每个区间的最大值,最小值分别存在X[][]和x[][]中。

那么X[][]x[][]所存储的分别是1×n的长方形内的最大值,最小值。X[i][j]存储第i行第j~j+n-1列的长方形中的最大值。同理,x[i][j]存储第i行第j~j+n-1列的长方形中的最小值。

这时再对这两个数组的每一列上的值进行维护,将X[][]中每个区间的的最大值用Y[ ][ ]维护,将x[][]中的每个区间的最小值用y[][]维护。那么Y[i][j]存储X[][]中第i~i+n-1行第j列的长方形的最大值。同理y[i][j]存储x[][]中第i~i+n-1行第j列的长方形的最小值。

Y[i][j]存储的实为以a[i~i+n-1][j~j+n-1]中的最大,即以i,j为左上角,边长为n的正方形中的最大值。同理,y[i][j]存储的即以i,j为左上角,边长为n的正方形中的最小值。

模拟过程见下图:

 Code

#include <bits/stdc++.h>
using namespace std; int n,m,k,front,FRONT,back,BACK,ans;
int a[][],q[],Q[];
int x[][],X[][];
int y[][],Y[][]; int main()
{
scanf("%d%d%d",&n,&m,&k);
for (int I=;I<=n;I++)
for (int i=;i<=m;i++)
scanf("%d",&a[I][i]);
for (int I=;I<=n;I++)
{
FRONT=BACK=front=back=Q[]=q[]=;
for (int i=;i<=m;i++)
{
while (a[I][i]>=a[I][Q[BACK]]&&FRONT<=BACK) BACK--;
while (a[I][i]<=a[I][q[back]]&&front<=back) back--;
BACK++;back++;Q[BACK]=i;q[back]=i;
while (i-Q[FRONT]>=k) FRONT++;
while (i-q[front]>=k) front++;
if (i>=k) X[I][i-k+]=a[I][Q[FRONT]],x[I][i-k+]=a[I][q[front]];
}
}
for (int I=;I<=m-k+;I++)
{
FRONT=BACK=front=back=Q[]=q[]=;
for (int i=;i<=n;i++)
{
while (X[i][I]>=X[Q[BACK]][I]&&FRONT<=BACK) BACK--;
while (x[i][I]<=x[q[back]][I]&&front<=back) back--;
BACK++;back++;Q[BACK]=i;q[back]=i;
while (i-Q[FRONT]>=k) FRONT++;
while (i-q[front]>=k) front++;
if (i>=k) Y[i-k+][I]=X[Q[FRONT]][I],y[i-k+][I]=x[q[front]][I];
}
}
ans=0x3f3f3f3f;
for (int I=;I<=n-k+;I++)
for (int i=;i<=m-k+;i++)
ans=min(ans,Y[I][i]-y[I][i]);
printf("%d\n",ans);
return ;
}

[P2216] [HAOI2007]理想的正方形 「单调队列」的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. P2216 [HAOI2007]理想的正方形 方法记录

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

随机推荐

  1. spark streaming 接收kafka消息之三 -- kafka broker 如何处理 fetch 请求

    首先看一下 KafkaServer 这个类的声明: Represents the lifecycle of a single Kafka broker. Handles all functionali ...

  2. Scala 学习之路(十一)—— 模式匹配

    一.模式匹配 Scala支持模式匹配机制,可以代替swith语句.执行类型检查.以及支持析构表达式等. 1.1 更好的swith Scala不支持swith,可以使用模式匹配match...case语 ...

  3. java源码解析之String类(五)

    /* * 切片函数,非常重要,这里一定要牢记beginIndex是开始位置,endIndex是结束位置,区别于以前学的offset是开始位置,而count或length是个数和长度 * 比如说,new ...

  4. 系统学习 Java IO (三)----文件类 File

    目录:系统学习 Java IO---- 目录,概览 Java IO API 中的 File 类可以访问基础文件系统. 使用 File 类,可以: 检查文件或目录是否存在. 如果目录不存在,创建一个目录 ...

  5. redhat6.0下配置DNS

    最近操作系统要结课,老师要求在redhat上配置各种服务器角色,包括dhcp.ftp.web.dns.前三个都还好,但就dns,被折磨的死去活来的,真让人头大.还好在同学的帮助下最后配置成功,实现了正 ...

  6. code forces 1173 C. Nauuo and Cards

    本文链接:https://www.cnblogs.com/blowhail/p/10990833.html Nauuo and Cards 原题链接:http://codeforces.com/con ...

  7. 网络IO-阻塞、非阻塞、IO复用、异步

    网络socket输入操作分为两个阶段:等待网络数据到达和将到达内核的数据复制到应用进程缓冲区.对这两个阶段不同的处理方式将网络IO分为不同的模型:IO阻塞模型.非阻塞模型.多路复用和异步IO. 一 阻 ...

  8. redis 是如何做持久化的

    Redis 是一个键值对数据库服务器.基于内存存储数据,它常被用做缓存数据库,用来替代 memcached.官网:https://redis.io/ 什么是持久化? 持久化,指将数据存储到可永久保存的 ...

  9. Java基本数据类型之间转换

    一.自动类型转换 转换的过程自动发生规则:小——>大byte->short->int->long->float->double char类型识别为int,可以转成i ...

  10. c++快速排序算法

    c++快速排序算法 题目描述 利用快速排序算法将读入的NN个数从小到大排序后输出. 快速排序是信息学竞赛的必备算法之一.对于快速排序不是很了解的同学可以自行上网查询相关资料,掌握后独立完成.(C++选 ...