博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷 P2216 [HAOI2007]理想的正方形
阅读量:4485 次
发布时间:2019-06-08

本文共 2533 字,大约阅读时间需要 8 分钟。

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

Description

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

Input

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

    第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。

Output

  • 仅一个整数,为ab矩阵中所有“nn正方形区域中的最大整数和最小整数的差值”的最小值。

Sample Input

5 4 21 2 5 60 17 16 016 17 2 12 10 2 11 2 2 2

Sample Output

1

题解:

  • 单调队列。
  • 一发A掉了,舒服。
  • 对于求出一个n * n的矩形中的最大值,可以想成求出n行中每行最大值中的最大值。每行的最大值怎么求?线段树、ST表都OK。但是用单调队列岂不是更好?
  • 所以先用单调队列求出以点(i, j)为第i行的j - n + 1 ~ j的格子中的最大/小值
  • 那么对于一个矩形我们只需要枚举n次就可以得到最大/小值了。
  • 但是,你用纸笔画画n * n矩形框选的范围。可以发现每次矩形都是整体向下挪了一个格子。那么这又是一个单调队列呀。只不过这次单调队列中的元素是以点(i, j)为第i行的j - n + 1 ~ j的格子中的最大/小值
  • 复杂度大概是O(2ab) = O(n ^ 2的规模)。
  • 哦,我偷懒用STL,常数巨大。不开O2 90pts,开了O2可以A。
#include 
#include
#include
#define N 1005#define inf 0x7fffffffusing namespace std;struct Node1{ int val, pos; friend bool operator < (Node1 x, Node1 y) { return x.val < y.val; }};struct Node2{ int val, pos; friend bool operator < (Node2 x, Node2 y) { return x.val > y.val; }};int n, m, len, ans = inf;int Max[N][N], Min[N][N];int read(){ int x = 0; char c = getchar(); while(c < '0' || c > '9') c = getchar(); while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();} return x;}int main(){ cin >> n >> m >> len; for(int i = 1; i <= n; i++) { priority_queue
que1; priority_queue
que2; for(int j = 1; j < len; j++) { int x = read(); que1.push((Node1){x, j}); que2.push((Node2){x, j}); } for(int j = len; j <= m; j++) { while(que1.size() && que1.top().pos <= j - len) que1.pop(); while(que2.size() && que2.top().pos <= j - len) que2.pop(); int x = read(); que1.push((Node1){x, j}); que2.push((Node2){x, j}); Max[i][j] = que1.top().val; Min[i][j] = que2.top().val; } } for(int j = len; j <= m; j++) { priority_queue
que1; priority_queue
que2; for(int i = 1; i < len; i++) { int v1 = Max[i][j]; int v2 = Min[i][j]; que1.push((Node1){v1, i}); que2.push((Node2){v2, i}); } for(int i = len; i <= n; i++) { while(que1.size() && que1.top().pos <= i - len) que1.pop(); while(que2.size() && que2.top().pos <= i - len) que2.pop(); int v1 = Max[i][j]; int v2 = Min[i][j]; que1.push((Node1){v1, i}); que2.push((Node2){v2, i}); ans = min(ans, que1.top().val - que2.top().val); } } cout << ans; return 0;}

转载于:https://www.cnblogs.com/BigYellowDog/p/11514929.html

你可能感兴趣的文章
《构建之法》(五)
查看>>
创建django项目
查看>>
Linux Bash基本功能
查看>>
一则小脚本(工作中用)
查看>>
软件工程结对作业
查看>>
Keil 4.0 生成bin文件
查看>>
sql语句的进化--hibernate篇
查看>>
python爬虫之cookie
查看>>
2017年5月29号课堂笔记
查看>>
HDU4247【瞎搞】
查看>>
lightoj 1125【背包·从n个选m个】
查看>>
HDU 1243 反恐训练营(最长公共序列)
查看>>
mysql数据库隔离级别
查看>>
(六)buildroot使用详解
查看>>
chrome修改UserAgent,调试
查看>>
Source Insight4.0 试用。。试用。。试用。。
查看>>
python循环for,range,xrange;while
查看>>
hadoop的节点间的通信
查看>>
HashMap
查看>>
mysql 主从 重新同步
查看>>