【简●解】[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\)的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: ...
随机推荐
- Android Handler消息机制源码解析
好记性不如烂笔头,今天来分析一下Handler的源码实现 Handler机制是Android系统的基础,是多线程之间切换的基础.下面我们分析一下Handler的源码实现. Handler消息机制有4个 ...
- HDU6050: Funny Function(推公式+矩阵快速幂)
传送门 题意 利用给出的式子求\(F_{m,1}\) 分析 直接推公式(都是找规律大佬) \(n为偶数,F_{m,1}=\frac{2(2^n-1)^{m-1}}3\) \(n为奇数,F_{m,1}= ...
- hdoj1027【STL系列。。。?】
这个太夸张了...感觉是有别的方法,但是觉得再说吧...以后碰到全排列应该也是用STL嗨的吧...嗯,,,就是这样的....?再说,再说.. 还有杭电支持c艹11,很棒 #include <bi ...
- bzoj 4240: 有趣的家庭菜园【树状数组+贪心】
以为是逆序对数-- 实际上,原数组移动若干次后我们会得到一个新的下标序列,需要的移动次数是这个新下标序列的逆序对数 然后我们要让这个最小,考虑贪心先按h把下标排一遍序,然后每次询问到一种值的时候,对每 ...
- Hexo瞎折腾系列(7) - Coding Pages申请SSL/TLS证书错误
问题 今天我的个人站点SSL/TLS证书到期,我的证书是由Coding Pages提供的,每次申请成功后有效期是三个月,证书到期后可以继续免费申请.但是当我登陆进入Coding Pages服务的后台并 ...
- bzoj 4456 [Zjoi2016]旅行者
题面 https://www.lydsy.com/JudgeOnline/problem.php?id=4456 题解 分治 设当前work的区间为(x1,y1,x2,y2) 我们将长边分成两半 不妨 ...
- 洛谷 P3480 [POI2009]KAM-Pebbles
https://www.luogu.org/problemnew/solution/P3480 讲不清楚... 首先对原序列做差分:设原序列为a,差分序列为d 那么,每一次按题意在原序列位置i处取走石 ...
- 二分查找 2015百度之星初赛1 HDOJ 5246 超级赛亚ACMer
题目传送门 /* 二分找到不大于m的最大的数,记做p,只要a[p] + k <= a[p+1]就继续 注意:特判一下当没有比m小的数的情况:) */ #include <cstdio> ...
- Android逆向分析工具表
逆向分析工具表 工具 描述 网址 androidterm Android Terminal Emulator http://code.google.com/p/androidterm/ droidbo ...
- archive log full ora-00257
############# sample 0 asmcmd show free 37G in archive_log ASMCMD> lsdgState Type Rebal Unbal Sec ...