【简●解】[HAOI2007] 理想的正方形
【题目大意】
有一个\(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] 理想的正方形的更多相关文章
- AC日记——[HAOI2007]理想的正方形 P2216
[HAOI2007] 理想的正方形 思路: 正解多个单调队列: 但是我用树套树水了过去: 来,上代码: #include <cstdio> #include <cstring> ...
- BZOJ1047: [HAOI2007]理想的正方形 [单调队列]
1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2857 Solved: 1560[Submit][St ...
- HAOI2007 理想的正方形
1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1402 Solved: 738[Submit][Sta ...
- RAM——[HAOI2007]理想的正方形
题目:[HAOI2007]理想的正方形 描述: [问题描述] 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. [输入]: 第一行为3个 ...
- bzoj 1047 : [HAOI2007]理想的正方形 单调队列dp
题目链接 1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2369 Solved: 1266[Submi ...
- BZOJ 1047: [HAOI2007]理想的正方形( 单调队列 )
单调队列..先对每一行扫一次维护以每个点(x, y)为结尾的长度为n的最大最小值.然后再对每一列扫一次, 在之前的基础上维护(x, y)为结尾的长度为n的最大最小值. 时间复杂度O(ab) (话说还是 ...
- 【BZOJ1047】[HAOI2007]理想的正方形(单调队列,动态规划)
[BZOJ1047][HAOI2007]理想的正方形(单调队列,动态规划) 题面 BZOJ 洛谷 题解 直接一个单调队列维护一下没给点和它前面的\(n\)个位置的最大值,再用一次单调队列维护连续\(n ...
- bzoj千题计划215:bzoj1047: [HAOI2007]理想的正方形
http://www.lydsy.com/JudgeOnline/problem.php?id=1047 先用单调队列求出每横着n个最大值 再在里面用单调队列求出每竖着n个的最大值 这样一个位置就代表 ...
- 【BZOJ1047】[HAOI2007]理想的正方形
[BZOJ1047][HAOI2007]理想的正方形 题面 bzoj 洛谷 题解 二维\(st\)表,代码是以前的 #include<iostream> #include<cstdi ...
- 【BZOJ1047】[HAOI2007]理想的正方形 (倍增ST表)
[HAOI2007]理想的正方形 题目描述 有一个\(a*b\)的整数组成的矩阵,现请你从中找出一个\(n*n\)的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: ...
随机推荐
- E20180425-hm
zoom n. 变焦; 嗡嗡声; 隆隆声; (车辆等) 疾驰的声音; deprecate vt. 不赞成,不推荐, 反对;
- bzoj 1823: [JSOI2010]满汉全席【2-SAT+tarjan】
因为每种食材只有一份,所以两个评委的如果有要求同一种食材的两种做法就是不可行,用这个来建立2-SAT模型 然后跑tarjan判可行性即可 #include<iostream> #inclu ...
- bzoj 1968: [Ahoi2005]COMMON 约数研究【枚举】
枚举约数,加上有这个约数的数个数 #include<iostream> #include<cstdio> using namespace std; const int N=10 ...
- Android中R.java丢失不见的解决方案
最近在做android项目时,遇到报错情况,于是clean了一下,结果java类全都报错了,里面的R下有红线,我一找,发现R.java不见了,真是奇怪,如下图(这是解决以后的): 然后查看了一下Con ...
- 交表(Send a Table)
#include<stdio.h> #include<string.h> #define N 50010 int phi[N],n,sum[N]; void phi_table ...
- tarjan有向图的强连通
强连通:在有向图G中,两个顶点间至少存在一条路径,则两个点强连通. 强连通图:在有向图中,每两个顶点都强连通,则有向图G就是一个强连通图. 强连通分量:在非强连通图中的极大强连通子图,就称为强连通分量 ...
- 为什么wait,notify和notifyAll要与synchronized一起使用?
https://blog.csdn.net/qq_39907763/article/details/79301813 Object.wait(),Object.notify(),Object.noti ...
- jquery html() 和text()的用法
html()类似JS中的 innerHTML,首先看一段代码: <!DOCTYPE html> <html lang="en"> <head> ...
- CSS3向外扩散的圆
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- [LuoGu]P2664 树上游戏
Portal 这题真的好. 看到树上路径, 脑子里就要点分治 这一题对于每个点都要计算一遍, 如果暴算实在不好算, 这样我们就可以考虑算贡献. 直接计算每种颜色的贡献. 因为一条过重心的路径中, 可能 ...