Solution 二维单调队列, 这个数组套起来看得我眼瞎... Code #include<cstdio> #include<algorithm> #include<cstring> #define rd read() #define rep(i,a,b) for(register int i = (a); i <= (b); ++i) #define per(i,a,b) for(register int i = (a); i >= (b); --i)…
[Luogu 2216] [HAOI2007]理想的正方形 题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示a,b,n的值 第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数.每行相邻两数之间用一空格分隔. 输出格式: 仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值. 输入输出样例 输入样例#1: 5 4 2 1 2…
1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2857  Solved: 1560[Submit][Status][Discuss] Description 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. Input 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数.每行相邻两数之间…
题目链接 1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2369  Solved: 1266[Submit][Status][Discuss] Description 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. Input 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数.每行相…
单调队列..先对每一行扫一次维护以每个点(x, y)为结尾的长度为n的最大最小值.然后再对每一列扫一次, 在之前的基础上维护(x, y)为结尾的长度为n的最大最小值. 时间复杂度O(ab) (话说还是deque2048ms快..list3572ms慢死了) #include<bits/stdc++.h> using namespace std; const int maxn = 1009; int X[maxn][maxn], R, C, N; int MN[maxn][maxn], MX[m…
题目链接:P2216 [HAOI2007]理想的正方形 题目描述 有一个 \(a\times b\)的整数组成的矩阵,现请你从中找出一个 \(n\times n\)的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入格式 第一行为3个整数,分别表示a,b,n的值 第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数.每行相邻两数之间用一空格分隔. 输出格式 仅一个整数,为 \(a\times b\)矩阵中所有" \(n\times n\)正方形区域中的最大整数和最小整数的差…
题意: 给出一个 N×M 的矩阵,以及一个数值 K ,求在给定的矩阵中取出一个 K×K 的矩阵其中最大值减去最小值的最小值. 细节: 没有细节来发暴力走天下,20分也是分啊~~~ QAQ. 分析: 感觉是一题裸体,大佬们看了一定秒切,但是本蒟蒻显然不会,二维不易可以先尝试如何求解在 1×K 的矩阵中求解答案呢,显然是利用一个数组 Max1[i][j] 表示第 i 行区间 [ j , j + K - 1] 的最大值,Min1[i][j] 表示第 i 行区间 [ j , j + K - 1] 的最小…
题意很简明吧? 枚举的矩形下边界和右端点即右下角,来确定矩形位置: 每一个纵列开一个单调队列,记录从 i-n+1 行到 i 行每列的最大值和最小值,矩形下边界向下推移的时候维护一下: 然后在记录的每一列的最大值和最小值上,跑滑动窗口,即用单调队列维护区间 [ j-n+1 , j ] 的最大值和最小值: 相当于维护了一个矩形的最大值和最小值 #include<cstdio> #include<iostream> #include<queue> #define R regi…
题目链接 Solution MD,经过这道题,算是掌握单调队列了... 可以先预处理出点 \((i,j)\) 往上 \(n\) 的最大值和最小值. 然后再横着做一遍单调队列即可. Code #include<bits/stdc++.h> #define in(x) x=read(); #define ll long long #define N 1001 using namespace std; ll read() { char ch=getchar(); ll f=1,w=0; while(…
洛谷P2216 )逼着自己写DP 题意: 给定一个带有数字的矩阵,找出一个大小为n*n的矩阵,这个矩阵中最大值减最小值最小. 思路: 先处理出每一行每个格子到前面n个格子中的最大值和最小值.然后对每一列求出长度为n的前面算出来的最大值的最大值,前面算出来的最小值的最小值.如果直接做是n的三次方,但是用单调队列优化后就是n方的. #include <algorithm> #include <iterator> #include <iostream> #include &l…
Code: #include<cstdio> #include<queue> #include<algorithm> using namespace std; #define maxn 1002 #define ll long long #define inf 100000000000 int minv[maxn][maxn], maxv[maxn][maxn]; struct Node{ ll val; int pos; Node(ll val=0,int pos=0…
#include<bits/stdc++.h> using namespace std; ; ; int a,b,n; int g[A][A],q[A][N],Q[A][N]; int head[A],tail[A]; int Head[A],Tail[A]; inline int read(){ ,f=;char ch=getchar(); ;ch=getchar();} )+(x<<)+(ch^);ch=getchar();} return x*f;} int main(){…
BZOJ原题链接 洛谷原题链接 显然可以用数据结构或\(ST\)表或单调队列来维护最值. 这里采用单调队列来维护. 先用单调队列维护每一行的最大值和最小值,区间长为正方形长度. 再用单调队列维护之前维护出的每行最值数组的每一列的最大值和最小值,区间同上. 最后维护出的数组其实就是以每个点为左上角的正方形中的最值,直接扫一遍求最小的差即可. 借用洛谷题解里大佬的图以更好说明: (\(X,x\)分别是维护出原矩阵中行的最大.最小值,\(Y,y\)分别是维护\(X,x\)中列的最大.最小值) #inc…
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1047 题意:给出一个n*m的矩阵.在所有K*K的子矩阵中,最大最小差值最小的是多少? 思路:枚举每一行,枚举每一列,(r,c),将(r-K+1,c-K+1)中的数字插入到单调队列中保存(这里设置两个单调队列,一个最大一个最小).每次计算以(r,c)为右下角的子矩阵的值时,判断队列头元素的列数是不是大于等于c-K+1,否则删掉队头.插入时,比如维护最小的单调队列,要判断队尾的元素是不是小…
开b组单调队列,分别维护此时某一列中的最大/最小值 然后我每次把它们的头取出来,塞到维护行的单调队列里,就是n*n的最大/最小值 #include<bits/stdc++.h> #define pa pair<int,int> #define CLR(a,x) memset(a,x,sizeof(a)) using namespace std; typedef long long ll; ; inline ll rd(){ ll x=;; ;c=getchar();} +c-',c…
题目戳这里 一句话题意 给你一个a×b的矩形,求一个n×n的子矩阵,矩阵里面的最大值和最小值之差最小. Solution 这个题目许多大佬都是单调队列,但是我不是很会,只好用了比较傻逼的方法: 首先我们预处理出每个点往后走N步的最大值和最小值.复杂度的话是\(O(a*b*n)\),然后枚举每一个点,往下走N步并比较最大值和最小值,就得到一个N×N的矩阵中的最大值和最小值,然后更新答案即可. 复杂度大概是 1e8,差不多正好卡过去.洛谷评测机是真的快,开氧气优化居然只要200ms Coding #…
[BZOJ1047][HAOI2007]理想的正方形(单调队列,动态规划) 题面 BZOJ 洛谷 题解 直接一个单调队列维护一下没给点和它前面的\(n\)个位置的最大值,再用一次单调队列维护连续\(n\)列的,每个数和前面\(n\)个数的最大值,最小值同理,就做完了. #include<iostream> #include<cstdio> using namespace std; #define MAX 1010 inline int read() { int x=0;bool t…
1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1402  Solved: 738[Submit][Status] Description 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. Input 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数.每行相邻两数之间用一空格分隔. Ou…
P2219 [HAOI2007]修筑绿化带 二维单调队列 写了这题 P2216 [HAOI2007]理想的正方形  后,你发现可以搞个二维单调队列 来保存矩形(i+1,i+A-1)(j+1,j+B-1)内矩形C*D的最小值 具体怎么搞呢 先搞出二维前缀和 蓝后先按$x$轴跑一遍单调队列,再按$y$轴跑一遍就好辣 #include<iostream> #include<cstdio> #include<cstring> using namespace std; inlin…
http://www.lydsy.com/JudgeOnline/problem.php?id=1047 先用单调队列求出每横着n个最大值 再在里面用单调队列求出每竖着n个的最大值 这样一个位置就代表了一个n*n矩阵的最大值 同理求出最小值 #include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 1001 int num[N][N]; int mx1[N…
[HAOI2007] 理想的正方形 思路: 正解多个单调队列: 但是我用树套树水了过去: 来,上代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; struct ReType { int mi,ma; }; struct TreeNodeType { int l,r,lc,rc,ma,mi,mid; };…
P2216 [HAOI2007]理想的正方形 题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示a,b,n的值 第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数.每行相邻两数之间用一空格分隔. 输出格式: 仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值. 输入输出样例 输入样例#1: 5 4 2 1 2 5 6 0 1…
[HAOI2007]理想的正方形 题目描述 有一个 \(a \times b\) 的整数组成的矩阵,现请你从中找出一个 \(n \times n\) 的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入格式 第一行为 \(3\) 个整数,分别表示 \(a,b,n\) 的值. 第二行至第 \(a+1\) 行每行为 \(b\) 个非负整数,表示矩阵中相应位置上的数.每行相邻两数之间用一空格分隔. 输出格式 仅一个整数,为 \(a \times b\) 矩阵中所有" \(n \times…
题目:[HAOI2007]理想的正方形 描述: [问题描述] 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. [输入]: 第一行为3个整数,分别表示a,b,n的值 第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数.每行相邻两数之间用一空格分隔. [输出]: 仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值. [输入样例] 5 4 2 1 2 5 6 0 17 16 0 16 17…
[BZOJ1047][HAOI2007]理想的正方形 题面 bzoj 洛谷 题解 二维\(st\)表,代码是以前的 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<vector> #include<queue> #include<…
[HAOI2007]理想的正方形 题目描述 有一个\(a*b\)的整数组成的矩阵,现请你从中找出一个\(n*n\)的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示\(a,b,n\)的值 第二行至第\(a+1\)行每行为\(b\)个非负整数,表示矩阵中相应位置上的数.每行相邻两数之间用一空格分隔. 输出格式: 仅一个整数,为\(a*b\)矩阵中所有\(n*n\)正方形区域中的最大整数和最小整数的差值"的最小值. 输入输出样例 输入样例…
理想的正方形 bzoj-1047 HAOI-2007 题目大意:有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 注释:$2\le a,b,n\le 10^3$,$n\le min(a,b)$. 想法:我的思路简直要死.通常的,我们优化暴力来完成对题目的求解.首先,想暴力.漂亮的暴力没想到,倒是想到一个a*b*n*n的,就是枚举每一个点,如果这个点可以作为n*n正方形的左上角,我就暴力枚举这个正方形的所有点.时间复杂度:O((a-n…
题目 这个题的算法核心就是求出以i,j为左上角,边长为n的矩阵中最小值和最大值.最小和最大值的求法类似. 单调队列做法: 以最小值为例: q1[i][j]表示第i行上,从j列开始的n列的最小值.$q1[i][j]=min(x[i][j],x[i][j+1],...,x[i][j+n-1])$$q1[i][1]=min(x[i][1],x[i][2],...,x[i][n])$$q1[i][2]=min(x[i][2],x[i][3],...,x[i][n+1])$类似滑动窗口,因此直接枚举行,对…
题目就是要求在n*m的矩形中找出一个k*k的正方形(理想正方形),使得这个正方形内最值之差最小(就是要维护最大值和最小值),显然我们可以用单调队列维护. 但是二维平面上单调队列怎么用? 我们先对行处理,将其压缩为一个(n-k+1)*m的矩形:再对列进行处理,最终压缩为一个(n-k+1)*(m-k+1)的矩形,枚举最大与最小之差,更新答案即可. 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e3+1; 4 int…
题目链接:BZOJ - 1047 题目分析 使用单调队列在 O(n^2) 的时间内求出每个 n * n 正方形的最大值,最小值.然后就可以直接统计答案了. 横向有 a 个单调队列(代码中是 Q[1] 到 Q[a] ),维护每行当前枚举区间的单调队列. 纵向一个单调队列(代码中是 Q[0] ),求出当前枚举区间的每行的单调队列后,就得到了每行的这个区间的最小值(最大值),就相当于一个长度为行数的数组,然后纵向做单调队列,求出的就是正方形的最值了. 代码 #include <iostream> #…