【题目大意】

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

【分析】

在暴力中想到优化,模仿曾经求二维前缀和的做法,先在每行求区间长度为\(n\)的最大值和最小值,再在此基础上求列上的最大值和最小值,则求得的即为单个\(n*n\)正方形矩阵中的最大值和最小值。(仔细体味下)

用单调队列就可以搞定,和滑动窗口类似。

【Code】

一个挣扎在英语一线的苦逼\(Oier\)。。。敲代码背单词。。。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int N = 1000 + 5;
const int INF = 0x7fffffff;
inline int read(){
int f = 1, x = 0;char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0'||ch>'9');
do {x = x*10+ch-'0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f*x;
}
int a, b, n, aa, bb, maps[N][N], ans = INF;
int shallow[N][N];// 肤浅的 adj. ---X最大值
int reform[N][N];// 改革,改进 v. ---X最小值
int allergic[N][N];// 敏感的 adj. ---Y最大值
int association[N][N];//协会,交往 n. ---Y最小值
int violence[20 * N];// 暴力行为 adj. ---队列
int head = 1, tail = 0; int main(){
a = read(), b = read(), n = read();
for (int i = 1;i <= a; ++i) {
for (int j = 1;j <= b; ++j) {
maps[i][j] = read();
}
}
aa = a - n + 1;
bb = b - n + 1; for (int i = 1;i <= a; ++i) {
head = 1, tail = 0;
// printf("rand %d : %d - %d \n", i, head, tail) ;
for (int j = 1;j <= b; ++j) {
while (maps[i][violence[tail]] <= maps[i][j] && head <= tail) tail--;
violence[++tail] = j;
while (head <= tail && violence[head] < j - n + 1) {
head++;
}
shallow[i][j] = maps[i][violence[head]];
}
} for (int i = 1;i <= a; ++i) {
head = 1, tail = 0;
// printf("rand %d : %d - %d \n", i, head, tail) ;
for (int j = 1;j <= b; ++j) {
while (maps[i][violence[tail]] >= maps[i][j] && head <= tail) tail--;
violence[++tail] = j;
while (head <= tail && violence[head] < j - n + 1) {
head++;
}
reform[i][j] = maps[i][violence[head]];
}
} // puts("");
// for (int i = 1;i <= a; ++i) {
// for (int j = 1; j <= b; ++j) {
// printf("%d ", reform[i][j]);
// }
// puts("");
// } for (int j = 1;j <= b; ++j) {
head = 1, tail = 0;
for (int i = 1;i <= a; ++i) {
while (shallow[violence[tail]][j] <= shallow[i][j] && head <= tail) tail--;
violence[++tail] = i;
while (head <= tail && violence[head] < i - n + 1) {
head++;
}
allergic[i][j] = shallow[violence[head]][j];
}
} // puts("");
// for (int i = 1;i <= a; ++i) {
// for (int j = 1; j <= b; ++j) {
// printf("%d ", allergic[i][j]);
// }
// puts("");
// } for (int j = 1;j <= b; ++j) {
head = 1, tail = 0;
for (int i = 1;i <= a; ++i) {
while (reform[violence[tail]][j] >= reform[i][j] && head <= tail) tail--;
violence[++tail] = i;
while (head <= tail && violence[head] < i - n + 1) {
head++;
}
association[i][j] = reform[violence[head]][j];
}
} // puts("");
// for (int i = 1;i <= a; ++i) {
// for (int j = 1; j <= b; ++j) {
// printf("%d ", association[i][j]);
// }
// puts("");
// } for (int i = n; i <= a; ++i) {
for (int j = n; j <= b; ++j) {
ans = min(ans, allergic[i][j] - association[i][j]);
}
} printf("%d", ans);
return 0;
}

【简●解】[HAOI2007] 理想的正方形的更多相关文章

  1. AC日记——[HAOI2007]理想的正方形 P2216

    [HAOI2007] 理想的正方形 思路: 正解多个单调队列: 但是我用树套树水了过去: 来,上代码: #include <cstdio> #include <cstring> ...

  2. BZOJ1047: [HAOI2007]理想的正方形 [单调队列]

    1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2857  Solved: 1560[Submit][St ...

  3. HAOI2007 理想的正方形

    1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1402  Solved: 738[Submit][Sta ...

  4. RAM——[HAOI2007]理想的正方形

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

  5. bzoj 1047 : [HAOI2007]理想的正方形 单调队列dp

    题目链接 1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2369  Solved: 1266[Submi ...

  6. BZOJ 1047: [HAOI2007]理想的正方形( 单调队列 )

    单调队列..先对每一行扫一次维护以每个点(x, y)为结尾的长度为n的最大最小值.然后再对每一列扫一次, 在之前的基础上维护(x, y)为结尾的长度为n的最大最小值. 时间复杂度O(ab) (话说还是 ...

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

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

  8. bzoj千题计划215:bzoj1047: [HAOI2007]理想的正方形

    http://www.lydsy.com/JudgeOnline/problem.php?id=1047 先用单调队列求出每横着n个最大值 再在里面用单调队列求出每竖着n个的最大值 这样一个位置就代表 ...

  9. 【BZOJ1047】[HAOI2007]理想的正方形

    [BZOJ1047][HAOI2007]理想的正方形 题面 bzoj 洛谷 题解 二维\(st\)表,代码是以前的 #include<iostream> #include<cstdi ...

  10. 【BZOJ1047】[HAOI2007]理想的正方形 (倍增ST表)

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

随机推荐

  1. (水题)洛谷 - P2089 - 烤鸡

    https://www.luogu.org/problemnew/show/P2089 非常暴力的dfs,不知道不剪枝会怎么样,但是其实最多也就 $3^{10}$ ,大不到哪里去.还有一个细节就是大于 ...

  2. 51nod 1247 可能的路径(gcd)

    传送门 题意 略 分析 有以下结论 \(1.(x,y)->(y,x)\) \(2.(x,y)->(a,b)==>(a,b)->(x,y)\) 证明 做如下变换 \((a,b)- ...

  3. 自己动手搭建SSM

    1.工具 apache-tomcat 7 apache-maven(后面详细讲!这东西我一开始也很懵逼) mysql 5以上的版本 navicat(有了这个就不用cmd了,可以直接显示数据库,如下图, ...

  4. bzoj 1814: Ural 1519 Formula 1【插头dp】

    设f[i][j][s]为轮廓线推到格子(i,j),状态为s的方案数 括号表示一段线的左端和右端,表示成左括号和右括号,状压的时候用1和2表示,0表示已经闭合 下面的蓝线是黄色格子的轮廓线,dp转移要把 ...

  5. 浅谈Floyd的三种用法 By cellur925

    Floyd大家可能第一时间想到的是他求多源最短路的n³算法.其实它还有另外两种算法的嘛qwq.写一发总结好了qwq. 一.多源最短路 放段代码跑,注意枚举顺序,用邻接矩阵存图.本质是一种动规. 复杂度 ...

  6. hdu1068 Girls and Boys 基础匈牙利

    #include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> ...

  7. sybase修改默认字符集为cp936

    原文地址:http://blog.sina.com.cn/s/blog_4d6854860100xn3f.html 报错信息:2402 error converting characters into ...

  8. MySql | 常用操作总结

    创建数据库: CREATE DATABASE 数据库名; 删除数据库名: drop database <数据库名>; 选择数据库: use 数据库名; 创建数据表: CREATE TABL ...

  9. Python标准库 urllib

    urllib是python的一个获取url的模块.它用urlopen函数的形式提供了一个非常简洁的接口.这使得用各种各样的协议获取url成为可能.它同时 也提供了一个稍微复杂的接口来处理常见的状况-如 ...

  10. Mysql的查询语句(联合查询、连接查询、子查询等)

    Mysql的各个查询语句(联合查询.连接查询.子查询等) 一.联合查询 关键字:union 语法形式 select语句1 union[union选项] select 语句2 union[union选项 ...