有乙個a∗b
a*ba∗
b的整數組成的矩陣,現請你從中找出乙個n*n的正方形區域,使得該區域所有數中的最大值和最小值的差最小。
輸入格式
第一行為3個整數,分別表示a,b,n的值
第二行至第a+1行每行為b個非負整數,表示矩陣中相應位置上的數。每行相鄰兩數之間用一空格分隔。
輸出格式
僅乙個整數,為ab矩陣中所有「nn正方形區域中的最大整數和最小整數的差值」的最小值。
輸入輸出樣例
輸入 #1
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
這題簡直就是為了單調佇列而單調佇列(當然可以用st表或線段樹)
簡要講講思路吧。
記f [i
][j]
f[i][j]
f[i][j
]表示從(i,
j)
(i,j)
(i,j
)這個點往右拓展 n
nn 個所能得到的最小值,g[i
][j]
g[i][j]
g[i][j
]為最大值。
假如我們已經得到了f[i
][j]
,g[i
][j]
f[i][j],g[i][j]
f[i][j
],g[
i][j
],那麼我們列舉每個點(i,
j)
(i,j)
(i,j
)之後,是不是相當於在這個點往後n
nn個到(i+
n,j)
(i+n,j)
(i+n,j
)這段區間裡找到 f
ff 陣列的最小值和 g
gg陣列的最大值。那我們從每一列的第一行開始掃起,是不是就變成了乙個大小為 n
nn 的滑動視窗的問題,每次求視窗的最小最大值,而這正是單調佇列能線性時間內解決的問題。
那麼f
ff 和 g
gg 陣列怎麼得到呢?我們從一維來看,是不是相當於每次求(i,
j)
(i,j)
(i,j)到(i,
j+n)
(i, j+n)
(i,j+n
)這段區間的最小和最大值?我們從第一列掃起,仍然是乙個滑動視窗問題啊!用單調佇列就可以求出 f
ff 和 g
gg陣列了!
所以我說這道題是單調佇列題!
#include #define n 1005
#define inf 2147483647
using namespace std;
int mp[n][n], f[n][n], g[n][n], q[n], x, y, p[n], a, b, ans = inf;
int main()
} for(i = 1; i <= n; i++)
} //for(i = 1; i <= n; i++) printf("%d\n", f[i][1]);
for(j = 1; j <= m - k + 1; j++)
} }printf("%d", ans);
return 0;
}
bzoj1047 haoi2007 理想正方形
time limit 10 sec memory limit 162 mb submit 2151 solved 1146 submit status discuss 有乙個a b的整數組成的矩陣,現請你從中找出乙個n n的正方形區域,使得該區域所有數中的最大值和最小值的差最小。第一行為3個整數,分...
BZOJ1047 HAOI2007 理想的正方形
佇列 題目傳送門 對於每一行用單調不增和單調不減佇列分別維護最小值和最大值。對於列,也用單調不增和單調不減佇列分別維護最小值和最大值。步驟如下 1 每一行分別把前 n 個數的單調佇列建好。2 取出每一行隊頭的元素用列的單調佇列維護並更新答案。3 把每一行在 2,n 1 的元素用單調佇列維護好,依次類...
1047 HAOI2007 理想的正方形
題目鏈結 題目大意 有乙個a b的整數組成的矩陣,現請你從中找出乙個n n的正方形區域,使得該區域所有數中的最大值和最小值的差最小。題解 顯然二維rmq就可以過了 但是用二維滑動視窗可以o n 2 維護 找矩陣中的最小值時維護單調上公升佇列,橫豎各一遍即可 我的收穫 單調佇列神啊 include i...