题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1047

题意:见中文题面

思路:该题是求二维的子矩阵的最大值与最小值的差值尽量小。所以可以考虑求出每个子矩阵的最大值和最小值。考虑一维求子段的最小值/最大值的思路。滑动窗口+单调队列。 转换成二维。设minNum[i][j]表示右下角为(i,j)的子矩阵的最小值。先对矩阵每一行用一维的做法求出每一行的子段的最小值,然后同样的方法求列的最值。注意在求列的子段最小值时比较的元素不是原矩阵的元素而是用行求的结果来比较。 具体看代码吧。

#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<queue>
#include<math.h>
#include<time.h>
#include<vector>
#include<iostream>
#include<string>
using namespace std;
typedef long long int LL;
const int MAXN = + ;
const int INF = 0x3f3f3f3f;
int n, m, k, num[MAXN][MAXN], minNum[MAXN][MAXN], maxNum[MAXN][MAXN];
void solve(int type, int seg[][MAXN]){
deque<pair<int, int> > deq;
for (int i = ; i <= n; i++){ //求行子段的最值。
deq.clear();
for (int j = ; j <= m; j++){
while (!deq.empty() && j - deq.front().second >= k){ deq.pop_front(); }
if (type){
while (!deq.empty() && deq.back().first < num[i][j]){ deq.pop_back(); }
}
else{
while (!deq.empty() && deq.back().first > num[i][j]){ deq.pop_back(); }
}
deq.push_back(make_pair(num[i][j], j));
seg[i][j] = deq.front().first;
}
}
for (int j = ; j <= m; j++){ //求列的最值
deq.clear();
for (int i = ; i <= n; i++){
while (!deq.empty() && i - deq.front().second >= k){ deq.pop_front(); }
if (type){
while (!deq.empty() && deq.back().first < seg[i][j]){ deq.pop_back(); }
}
else{
while (!deq.empty() && deq.back().first > seg[i][j]){ deq.pop_back(); }
}
deq.push_back(make_pair(seg[i][j], i));
seg[i][j] = deq.front().first;
}
}
}
int main(){
//#ifdef kirito
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
//#endif
// int start = clock();
while (~scanf("%d%d%d", &n, &m, &k)){
for (int i = ; i <= n; i++){
for (int j = ; j <= m; j++){
scanf("%d", &num[i][j]);
}
}
int ans = INF;
solve(, minNum); solve(, maxNum);
////Debug
//printf("minNum Segment:\n");
//for (int i = 1; i <= n; i++){
// for (int j = 1; j <= m; j++){
// printf("%d ", minNum[i][j]);
// }
// printf("\n");
//}
//printf("maxNum Segment:\n");
//for (int i = 1; i <= n; i++){
// for (int j = 1; j <= m; j++){
// printf("%d ", maxNum[i][j]);
// }
// printf("\n");
//}
for (int i = k; i <= n; i++){
for (int j = k; j <= m; j++){
ans = min(ans, maxNum[i][j] - minNum[i][j]);
}
}
printf("%d\n", ans);
}
//#ifdef LOCAL_TIME
// cout << "[Finished in " << clock() - start << " ms]" << endl;
//#endif
return ;
}

BZOJ 1047 二维单调队列的更多相关文章

  1. bzoj1047-理想的正方形(二维单调队列)

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

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

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

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

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

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

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

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

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

  6. bzoj 2216: Lightning Conductor 单调队列优化dp

    题目大意 已知一个长度为\(n\)的序列\(a_1,a_2,...,a_n\)对于每个\(1\leq i\leq n\),找到最小的非负整数\(p\)满足: 对于任意的\(j\), \(a_j \le ...

  7. BZOJ 1855 股票交易(单调队列优化DP)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1855 题意:最近lxhgww又迷上了投资股票, 通过一段时间的观察和学习,他总结出了股票 ...

  8. BZOJ 2424 订货(贪心+单调队列)

    怎么题解都是用费用流做的啊...用单调队列多优美啊. 题意:某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月初 ...

  9. BZOJ 1012 线段树||单调队列

    非常裸的线段树  || 单调队列: 假设一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然不管在如何的情况下都不会被选为最大值. 既然它仅仅在末尾选.那么自然能够满足以上的条件 ...

随机推荐

  1. Linux PXE无盘工作站

    • 关于PXE无盘工作站系统的简介 PXE无盘工作站系统是指由一台或多台“系统服务器”和多台“PXE客户端(无盘工作站)”通过 交换机 相连组成的局域网系统. (图1:无盘工作站系统部署拓扑图) • ...

  2. CSS3教程:box-sizing属性的理解

    说到 IE 的 bug,一个臭名昭著的例子是它对于“盒模型”的错误解释:在 IE5.x 以及 Quirks 模式的 IE6/7 中,将 border 与 padding 都包含在 width 之内.这 ...

  3. Android 常用开发工具以及Mac常用软件

    Android 常用的开发工具记录.其中包括AndroidStudio(IDEA)插件.Mac 上好用的软件以及国内知名Android开发者博客等. Android Studio 插件 codota ...

  4. VirtualBox注册Com对象失败解决方法

    (1)用CMD命令进入VirtualBox安装目录 (2)在VirtualBox目录下输入命令VBoxSVC /ReRegServer并执行 (3)在VirtualBox目录下输入命令regsvr32 ...

  5. Visual Studio 默认保存为UTF8编码

    Visual Studio (中文版)默认保存的文本文件是GB2312编码(代码页936)的,默认的行尾(End of line)是CRLF的. 如果仅仅是在windows下开发问题也不大,但是涉及到 ...

  6. Mosquitto pub/sub服务实现代码浅析-主体框架

    Mosquitto 是一个IBM 开源pub/sub订阅发布协议 MQTT 的一个单机版实现(目前也只有单机版),MQTT主打轻便,比较适用于移动设备等上面,花费流量少,解析代价低.相对于XMPP等来 ...

  7. ADT for Eclipse无法升级到23.0的解决方法(确保您的网络能够访问google的地址)

    进行以下步骤时,请确保您的网络能够访问google的地址,因为有可能是无法访问google地址导致无法升级,该文不是为了解决这个问题!!! 最近一次的升级,ADT无法从ADT 22.X升级到23.0. ...

  8. Python之路,Day6 - Python基础6

    本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configpars ...

  9. Android studio 英文——中文 翻译插件

    TranslationPlugin 1.手动下载 TranslationPlugin ,在Android studio 中 2. 3. 4.选中文件,点击OK 5.设置快捷键 代号1 : 代号2 :

  10. Sass 的调试

    Sass 的调试 Sass 调试一直以来都是一件头痛的事情,使用 Sass 的同学都希望能在浏览器中直接调试 Sass 文件,能找到对应的行数.值得庆幸的是,现在实现并不是一件难事,只要你的浏览器支持 ...