有乙個a*b的整數組成的矩陣,現請你從中找出乙個n*n的正方形區域,使得該區域所有數中的最大值和最小值的差最小。
第一行為3個整數,分別表示a,b,n的值
第二行至第a+1行每行為b個非負整數,表示矩陣中相應位置上的數。每行相鄰兩數之間用一空格分隔。
僅乙個整數,為a*b矩陣中所有「n*n正方形區域中的最大整數和最小整數的差值」的最小值。
輸入 #1複製
5 4 2輸出 #1複製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
直接暴力o(a*b*n*n),想辦法優化
我們發現正方形的邊長固定,要在這個固定的區間中找最小值與最大值的最小差
固定區間,嗯,考慮考慮單調佇列?
(雖說其他的資料結構也可以)
既然是二維的,怎麼實現呢,單調佇列可是線性的
這個好辦,先處理行,再用行的結果處理列就好
怎麼想到呢
我們分析自己的暴力程式,發現在處理最大最小值時做了很多無用功
這根線性的題分析是一樣的
處理最大最小值有單調佇列優化
先處理行:
根據行的結論處理列:
好啦
1view code/***********************
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()
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...