BZOJ原题链接

洛谷原题链接

显然可以用数据结构或\(ST\)表或单调队列来维护最值。

这里采用单调队列来维护。

先用单调队列维护每一行的最大值和最小值,区间长为正方形长度。

再用单调队列维护之前维护出的每行最值数组的每一列的最大值和最小值,区间同上。

最后维护出的数组其实就是以每个点为左上角的正方形中的最值,直接扫一遍求最小的差即可。

借用洛谷题解里大佬的图以更好说明:



(\(X,x\)分别是维护出原矩阵中行的最大、最小值,\(Y,y\)分别是维护\(X,x\)中列的最大、最小值)

#include<cstdio>
using namespace std;
const int N = 1010;
const int M = 2e6 + 10;
int a[N][N], ma_x[N][N], mi_x[N][N], ma_y[N][N], mi_y[N][N], qma[M], qmi[M];
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline int minn(int x, int y)
{
return x < y ? x : y;
}
int main()
{
int i, j, n, m, k, lmi, lma, rmi, rma, o, oo, mi = 1e9;
n = re();
m = re();
k = re();
for (i = 1; i <= n; i++)
for (j = 1; j <= m; j++)
a[i][j] = re();
for (i = 1; i <= n; i++)
{
lmi = lma = 1;
rmi = rma = 0;
for (j = 1; j < k; j++)
{
for (; lma <= rma && a[i][qma[rma]] <= a[i][j]; rma--);
for (; lmi <= rmi && a[i][qmi[rmi]] >= a[i][j]; rmi--);
qma[++rma] = j;
qmi[++rmi] = j;
}
for (; j <= m; j++)
{
for (; lma <= rma && j - qma[lma] + 1 > k; lma++);
for (; lmi <= rmi && j - qmi[lmi] + 1 > k; lmi++);
for (; lma <= rma && a[i][qma[rma]] <= a[i][j]; rma--);
for (; lmi <= rmi && a[i][qmi[rmi]] >= a[i][j]; rmi--);
qma[++rma] = j;
qmi[++rmi] = j;
ma_x[i][j - k + 1] = a[i][qma[lma]];
mi_x[i][j - k + 1] = a[i][qmi[lmi]];
}
}
for (i = 1, o = m - k + 1; i <= o; i++)
{
lmi = lma = 1;
rmi = rma = 0;
for (j = 1; j < k; j++)
{
for (; lma <= rma && ma_x[qma[rma]][i] <= ma_x[j][i]; rma--);
for (; lmi <= rmi && mi_x[qmi[rmi]][i] >= mi_x[j][i]; rmi--);
qma[++rma] = j;
qmi[++rmi] = j;
}
for (; j <= n; j++)
{
for (; lma <= rma && j - qma[lma] + 1 > k; lma++);
for (; lmi <= rmi && j - qmi[lmi] + 1 > k; lmi++);
for (; lma <= rma && ma_x[qma[rma]][i] <= ma_x[j][i]; rma--);
for (; lmi <= rmi && mi_x[qmi[rmi]][i] >= mi_x[j][i]; rmi--);
qma[++rma] = j;
qmi[++rmi] = j;
ma_y[j - k + 1][i] = ma_x[qma[lma]][i];
mi_y[j - k + 1][i] = mi_x[qmi[lmi]][i];
}
}
for (i = 1, o = n - k + 1, oo = m - k + 1; i <= o; i++)
for (j = 1; j <= oo; j++)
mi = minn(mi, ma_y[i][j] - mi_y[i][j]);
printf("%d", mi);
return 0;
}

BZOJ1047或洛谷2216 [HAOI2007]理想的正方形的更多相关文章

  1. 洛谷 2216 [HAOI2007]理想的正方形

    题目戳这里 一句话题意 给你一个a×b的矩形,求一个n×n的子矩阵,矩阵里面的最大值和最小值之差最小. Solution 这个题目许多大佬都是单调队列,但是我不是很会,只好用了比较傻逼的方法: 首先我 ...

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

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

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

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

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

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

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

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

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

    题目大意:有一个$a\times b$的矩阵,求一个$n\times n$的矩阵,使该区域中的极差最小. 题解:二维$ST$表,每一个点试一下是不是左上角就行了 卡点:1.用了一份考试时候写的二维$S ...

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

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

  8. [Luogu 2216] [HAOI2007]理想的正方形

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

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

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

随机推荐

  1. Bad owner or permissions on .ssh/config的解决

    出处:http://blog.csdn.net/notzuonotdied/article/details/69668519 在.ssh目录,执行以下命令行: sudo chmod 600 confi ...

  2. 学习BOS物流项目第九天

    1 教学计划 1.业务受理需求分析 a. 业务通知单 b.工单 c.工作单 2.创建业务受理环节的数据表 a.业务通知单 b.工单 c.工作单 3.实现业务受理自动分单 a.在CRM服务端扩展方法根据 ...

  3. ES5新增数组方法every()、some()、filter()、map()

    JavaScript ES5标准中新增了一些Array方法,如every().some().filter().map().它们的出现使我们能够更加便利地操作数组,但对IE9以下浏览器的兼容性比较差.下 ...

  4. DNS隧道 iodns

    通过iodns这个工具也能搭建DNS隧道 iodns的优点: 对下行数据不进行编码,速度快 支持多平台 最大16个并发连接 强制密码设定 iodns创建的DNS隧道网段不能喝服务器,客户端同一网段,比 ...

  5. linux下外接显示器亮度调节

    下载Brightness Controller 即可调节. 还可以通过如下命令: 使用xrandr | grep -v disconnected | grep connected命令查看连接的显示设备 ...

  6. 【scrapy】其他问题2

    今天爬取豆瓣电影的是时候,出现了两个问题: 1.数据无法爬取并输出Retrying <GET https://movie.douban.com/robots.txt> 看起来像是被拦截了. ...

  7. 【MongoDB】关于无法连接mongo的问题

    今天使用MongoDB的时候发现直接输入mongo提示连接失败 首先想到的可能是服务还没启动 当我随便打开一个cmd输入net start MongoDB 提示:net start mongodb 发 ...

  8. linux安装zookeeper及使用

    一.安装条件 想要安装zookeeper,必须先在linux中安装好jdk.安装步骤见: https://www.cnblogs.com/expiator/p/9987351.html 二.下载并解压 ...

  9. vue中使用全局函数

    方法一: 在mian.js中写入函数: Vue.prototype.bb = function () {        alert('OK'); } 然后在任何组件中都可以调用: this.bb() ...

  10. c++面向过程和面向对象-C++编译器是如何管理类和对象的

    1,c++编译时如何区分对象调用类的方法? C++中的class从面向对象理论出发,将变量(属性)和函数(方法)集中定义在一起,用于描述现实世界中的类.从计算机的角度,程序依然由数据段(栈区内存)和代 ...