time limit: 10 sec
memory limit: 162 mb
submit: 2151
solved: 1146 [
submit][
status][
discuss]
有乙個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 2 1
2 10 2 1
1 2 2 2
1問題規模
(1)矩陣中的所有數都不超過1,000,000,000
(2)20%的資料2<=a,b<=100,n<=a,n<=b,n<=10
(3)100%的資料2<=a,b<=1000,n<=a,n<=b,n<=100
令f[i][j]=max(w[i][j-n+1],w[i][j-n+2],…,w[i][j]),g[i][j]=max(w[i-n+1][j],w[i-n+2][j],…,w[i][j])。那麼g[i][j]即為以(i,j)為左下角點的n*n區域中最大值。同理,可求得n*n區域中最小值。
在求f[i][j]和g[i][j]時可用單調佇列。
#include#include#include#include#include#define f(i,j,n) for(int i=j;i<=n;i++)
#define d(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
using namespace std;
int n,a,b,l1,l2,r1,r2,ans;
int w[1005][1005],f[1005][1005][2],g[1005][1005][2],p[1005][2],q[1005][2];
int main()
f(j,n,b)
f(i,n,a)
{ while (p[r1][0]<=f[i][j][0]&&r1>=l1) r1--;
p[++r1][0]=f[i][j][0];
p[r1][1]=i;
while (p[l1][1]=f[i][j][1]&&r2>=l2) r2--;
q[++r2][0]=f[i][j][1];
q[r2][1]=i;
while (q[l2][1]
bzoj1047 haoi2007 理想的正方形
有乙個a b a ba b的整數組成的矩陣,現請你從中找出乙個n n的正方形區域,使得該區域所有數中的最大值和最小值的差最小。輸入格式 第一行為3個整數,分別表示a,b,n的值 第二行至第a 1行每行為b個非負整數,表示矩陣中相應位置上的數。每行相鄰兩數之間用一空格分隔。輸出格式 僅乙個整數,為ab...
BZOJ1047 HAOI2007 理想的正方形
佇列 題目傳送門 對於每一行用單調不增和單調不減佇列分別維護最小值和最大值。對於列,也用單調不增和單調不減佇列分別維護最小值和最大值。步驟如下 1 每一行分別把前 n 個數的單調佇列建好。2 取出每一行隊頭的元素用列的單調佇列維護並更新答案。3 把每一行在 2,n 1 的元素用單調佇列維護好,依次類...
1047 HAOI2007 理想的正方形
題目鏈結 題目大意 有乙個a b的整數組成的矩陣,現請你從中找出乙個n n的正方形區域,使得該區域所有數中的最大值和最小值的差最小。題解 顯然二維rmq就可以過了 但是用二維滑動視窗可以o n 2 維護 找矩陣中的最小值時維護單調上公升佇列,橫豎各一遍即可 我的收穫 單調佇列神啊 include i...