luogu 2216 理想的正方形

2022-07-17 05:39:11 字數 2050 閱讀 4679

有乙個a*b的整數組成的矩陣,現請你從中找出乙個n*n的正方形區域,使得該區域所有數中的最大值和最小值的差最小。

第一行為3個整數,分別表示a,b,n的值

第二行至第a+1行每行為b個非負整數,表示矩陣中相應位置上的數。每行相鄰兩數之間用一空格分隔。

僅乙個整數,為a*b矩陣中所有「n*n正方形區域中的最大整數和最小整數的差值」的最小值。

輸入 #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)矩陣中的所有數都不超過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

直接暴力o(a*b*n*n),想辦法優化

我們發現正方形的邊長固定,要在這個固定的區間中找最小值與最大值的最小差

固定區間,嗯,考慮考慮單調佇列?

(雖說其他的資料結構也可以)

既然是二維的,怎麼實現呢,單調佇列可是線性的

這個好辦,先處理行,再用行的結果處理列就好

怎麼想到呢

我們分析自己的暴力程式,發現在處理最大最小值時做了很多無用功

這根線性的題分析是一樣的

處理最大最小值有單調佇列優化

先處理行:

根據行的結論處理列:

好啦

1

/***********************

2user:mandy.h.y

3language:c++

4problem:luogu 2216

5algorithm:

6date:2019.9.4

7***********************/8

9 #include10

11using

namespace

std;

1213

const

int maxn = 1005;14

15int

n,m,l;

16int

a[maxn][maxn];

17int

l1,r1,l2,r2;

18int

q1[maxn],q2[maxn];

19int

mx1[maxn][maxn],mx2[maxn][maxn];

20int

my1[maxn][maxn],my2[maxn][maxn];

2122 templateinline void read(t &x)

2829 templatevoid putch(const

t x)

3334 templatevoid put(const

t x)

3839

void

file()

4344

void

readdata()

5051

void

work()73}

74//

列 75

for(int i = 1;i <= m; ++i)95}

96int ans =2e9;

97for(int i = l;i <= n; ++i)

98for(int j = l;j <= m; ++j)

101put(ans);

102}

103104

intmain()

view code

P2216 HAOI2007 理想的正方形()

題目鏈結 有乙個a乘b的整數組成的矩陣,現請你從中找出乙個nn的正方形區域,使得該區域所有數中的最大值和最小值的差最小。輸入輸出格式 輸入格式 第一行為3個整數,分別表示a,b,n的值 第二行至第a 1行每行為b個非負整數,表示矩陣中相應位置上的數。每行相鄰兩數之間用一空格分隔。輸出格式 僅乙個整數...

P2216 HAOI2007 理想的正方形

有乙個a b的整數組成的矩陣,現請你從中找出乙個n n的正方形區域,使得該區域所有數中的最大值和最小值的差最小。輸入格式 第一行為3個整數,分別表示a,b,n的值 第二行至第a 1行每行為b個非負整數,表示矩陣中相應位置上的數。每行相鄰兩數之間用一空格分隔。輸出格式 僅乙個整數,為a b矩陣中所有 ...

P2216 HAOI2007 理想的正方形

有乙個 a b 的整數組成的矩陣,現請你從中找出乙個 n n 的正方形區域,使得該區域所有數中的最大值和最小值的差最小。輸入格式 第一行為三個整數,分別表示 a,b,n 的值 第二行至第 a 1 行每行為 b 個非負整數,表示矩陣中相應位置上的數。輸出格式 輸出僅乙個整數,為 a b 矩陣中所有 n...