bzoj1047 haoi2007 理想的正方形

2021-09-26 06:35:07 字數 1830 閱讀 4694

有乙個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...