题目传送门

有一个 a×b 的整数组成的矩阵,现请你从中找出一个 n×n 的正方形区域,使得该区域所有数中的最大值和最小值的差最小。

输入格式

第一行为三个整数,分别表示 a,b,n 的值;

第二行至第 a+1 行每行为 b 个非负整数,表示矩阵中相应位置上的数。

输出格式

输出仅一个整数,为 a×b 矩阵中所有“n×n 正方形区域中的最大整数和最小整数的差值”的最小值。

数据范围

2≤a,b≤1000
n≤a,n≤b,n≤100
矩阵中的所有数都不超过 109。

输入样例:

5 4 2
1 2 5 6
0 17 16 0
16 17 2 1
2 10 2 1
1 2 2 2

输出样例:

1

题解:

1.对于每一行,我们先求出以 i 为右端点的, 且长度在n的范围内的最大值和最小值, 分别存到row_max[i] 和

row_min[i] 中去

2.对于每一列, 我们遍历已经得到的 row_max 数组和 row_min 数组, 分别得到在这一列上以j为右下端点,且长

度在n的范围内的最大值和最小值分别存储到 b[j] 和 c[j] 中去,这样我们就得到了以 (i, j) 为右下顶点且行和列的长度为 n 的矩阵的最大值和最小值

3.遍历所有的列的同时,求出max(b[j] - c[j]) 就是最终的答案

#include<iostream>
using namespace std;
const int N = 1010;
int w[N][N], row_min[N][N], row_max[N][N];
int st[N];
int n, m, k;
void get_min(int a[], int b[], int n)  //获取最小值,
{int l = 0, r = -1;for(int i = 1; i <= n; i++){while(l <= r && i - st[l] >= k)l++;while(l <= r && a[i] <= a[st[r]])r--;st[++r] = i;b[i] = a[st[l]];}
}
void get_max(int a[], int b[], int n)   //获取最大值
{int l = 0, r = -1;for(int i = 1; i <= n; i++){while(l <= r && i - st[l] >= k)l++;while(l <= r && a[i] >= a[st[r]])r--;st[++r] = i;b[i] = a[st[l]];}
}
int main()
{scanf("%d%d%d", &n, &m, &k);for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)scanf("%d", &w[i][j]);for(int i = 1; i <= n; i++){get_min(w[i], row_min[i], m);get_max(w[i], row_max[i], m);}int ans = 1e9;int a[N], b[N], c[N];for(int i = k; i <= m; i++){for(int j = 1; j <= n; j++) a[j] = row_max[j][i];get_max(a, b, n);for(int j = 1; j <= n; j++) a[j] = row_min[j][i];get_min(a, c, n);for(int j = k; j <= n; j++) ans = min(ans, b[j] - c[j]);}cout << ans << endl;return 0;
}

AcWing1091.理想的正方形(单调队列DP)相关推荐

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

    题目链接:https://www.luogu.org/problem/P2216 题意:求给定n*m的矩形中所有k*k的正方形块中最大值最小值之差(极差)最小 哇,大神的思路真的很帅 单调队列对每一行 ...

  2. BZOJ 1047 理想的正方形(单调队列)

    刚开始用二维RMQ直接给超内存了... 用单调队列可以做到O(n^2)的复杂度.具体是先把每行用单调队列处理一下.再把处理后的用列单调队列处理下. # include <cstdio> # ...

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

    题目链接 Solution MD,经过这道题,算是掌握单调队列了... 可以先预处理出点 \((i,j)\) 往上 \(n\) 的最大值和最小值. 然后再横着做一遍单调队列即可. Code #incl ...

  4. BZOJ 1047: [HAOI2007]理想的正方形 单调队列瞎搞

    题意很简明吧? 枚举的矩形下边界和右端点即右下角,来确定矩形位置: 每一个纵列开一个单调队列,记录从 i-n+1 行到 i 行每列的最大值和最小值,矩形下边界向下推移的时候维护一下: 然后在记录的每一 ...

  5. bzoj1047/luogu2216 理想的正方形 (单调队列)

    开b组单调队列,分别维护此时某一列中的最大/最小值 然后我每次把它们的头取出来,塞到维护行的单调队列里,就是n*n的最大/最小值 1 #include<bits/stdc++.h> 2 # ...

  6. bzoj1047 [HAOI2007]理想的正方形 单调队列

    这种在矩形里面找矩形有固定的套路,不是容斥就是左右上下延伸,这个题就是向左向右延伸.. 然后手玩优化发现邻位转移比暴力要好一些,可以用splay统计,但复杂度不对 然后由于每一行互不影响于是可以单行同 ...

  7. bzoj1791,P4381-[IOI2008]Island【基环树,树形dp,单调队列dp,树的直径】

    正题 评测记录:https://www.luogu.org/recordnew/lists?uid=52918&pid=P4381 题目大意 有n个岛,n条无向边(保证每个岛都有边连到).走过 ...

  8. P3580 [POI2014]ZAL-Freight(单调队列dp)

    P3580 [POI2014]ZAL-Freight(单调队列dp) 考虑两辆车怎么样是最优的. t1,t2,St_1,t_2,St1​,t2​,S t1+St_1+St1​+S 第一辆车:[t1,t ...

  9. 刷题总结——烽火传递(单调队列+dp)

    题目: 题目描述 烽火台又称烽燧,是重要的防御设施,一般建在险要处或交通要道上.一旦有敌情发生,白天燃烧柴草,通过浓烟表达信息:夜晚燃烧干柴,以火光传递军情.在某两座城市之间有 n 个烽火台,每个烽火 ...

最新文章

  1. vs2010 vc nmake编译openssl-0.9.8e
  2. 【深度学习】用Pytorch给你的母校做一个样式迁移吧!
  3. 从服务器恢复系统,服务器恢复系统
  4. 华为鸿蒙系统支持什么手机_什么样的手机可以刷鸿蒙系统?看看你的手机支持吗?...
  5. ic 卡获取帐号apdu指令_《全球行动》携手京东校园送福利 1000元京东卡等你拿
  6. Python风格总结: OS 文件/目录方法
  7. ORCLE conn连接报错
  8. 教育统计与测量【1】
  9. 计算机制图系统的组成,lesson02-计算机机地图制图系统的组成.ppt
  10. SAI颈部正面的画法
  11. 蓝牙HID——将android设备变成蓝牙鼠标/触控板(BluetoothHidDevice)
  12. idea git暂存操作
  13. WebLogic 10.3.1 下载地址
  14. 什么是PWM 和PFM?
  15. Matlab中创建和使用表
  16. python计算频率_如何计算给定波的频率和时间
  17. mac PhotoshopCS6 破解安装
  18. pyqt5制作指示灯
  19. Java ME引路蜂地图开发示例:第一个地图应用
  20. python3GUI--200行代码写一个上课点名程序(附源码)

热门文章

  1. 前端优化-Img与background
  2. h2database源码浅析:TransactionMap、MVMap、MVStore
  3. mybatis3源码1-初始化
  4. python collection 和 heapq 模块使用说明
  5. 结构化元素、网页结构和iframe内联框架
  6. Asp.net MVC权限设计思考 (一)数据库建库部分
  7. 《剑指 Offer I》刷题笔记 11 ~ 19 题
  8. 我从别人那里偷学的前端调试小技巧(浏览器篇)
  9. Mysql修改数据库密码的几种方法
  10. 通过as3直接操作swf文件的元件