有乙個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^2)暴力了 ,但是貌似20都沒有(好像是有的。。但是沒卵用=),去看看神犇們的題解吧.
-> ->然而單調佇列是個什麼東西 ,好像從來沒寫過的樣子.
-> ->將原矩陣分為b列 每一列進行一次滑動視窗單調佇列 視窗長就是n嘛
-> ->然後開陣列記下來 比如說max[i][j]表示從第i行第j-n+1列到第j列的最大值之類的
-> ->這個時候n行被壓縮成了一行(只要求最大值嘛) 然後利用max[i][j]再來一發單調佇列 這時候每n個點就被壓成了乙個點 開陣列記下來 比如max[i][j]表示以i,j為右下角的n*n的矩形的最大值
-> ->最小值也像上面這樣搞就好了 然後暴力(a-n)*(b-n)找最小差值
-> ->其實就是4次單調佇列= = 未曾見過如此之神題(也勉強算dp吧?)
(輸入資料有一百萬)(四次單調佇列都差不多,複製即可,只是要注意豎著滑視窗的時候變的是第一維而非第二維)(不想用deque所以手寫了佇列 覺得兩個佇列一起寫很蛋疼於是寫了4個函式= =)
#include
#include
#include
#include
using
namespace
std;
const
int maxn=1000+10;
const
int inf=(1
<<30);
int a,b,n,map[maxn][maxn];
int max[maxn][maxn],min[maxn][maxn];
int max[maxn][maxn],min[maxn][maxn];
int read()
void init_data()
void cal0(int x)// cal max downer 從上往下豎著壓大的
,rear,front;
win[1]=1;
rear=front=1;
for(int i=2;i<=a;i++)
if(i>=n) max[i][x]=map[win[rear]][x];
}}void cal1(int x)// cal min upper 從上往下壓小的
,rear,front;
win[1]=1;
rear=front=1;
for(int i=2;i<=a;i++)
if(i>=n) min[i][x]=map[win[rear]][x];
}}void cal2(int x)//利用已經壓出來的max橫著壓成max
,rear,front;
win[1]=1;
rear=front=1;
for(int i=2;i<=b;i++)
if(i>=n) max[x][i]=m[win[rear]];
}}void cal3(int x)//類似
,rear,front;
win[1]=1;
rear=front=1;
for(int i=2;i<=b;i++)
if(i>=n) min[x][i]=m[win[rear]];
}}int main()
dp神題%%%
HAOI2007 理想的正方形
時間限制 10 sec 記憶體限制 162 mb 有乙個a b的整數組成的矩陣,現請你從中找出乙個n n的正方形區域,使得該區域所有數中的最大值和最小值 的差最小。第一行為3個整數,分別表示a,b,n的值第二行至第a 1行每行為b個非負整數,表示矩陣中相應位置上的數。每 行相鄰兩數之間用一空格分隔。...
HAOI2007 理想的正方形
有乙個a b的整數組成的矩陣,現請你從中找出乙個n n的正方形區域,使得該區域所有數中的最大值和最小值的差最小.第一行為3個整數,分別表示a,b,n的值第二行至第a 1行每行為b個非負整數,表示矩陣中相應位置上的數.每行相鄰兩數之間用一空格分隔.100 的資料2 a,b 1000,n a,n b,n...
HAOI2007 理想的正方形
x與x所儲存的分別是1 n的長方形內的最大值,最小值。x i j 儲存第i行第jj n 1列的長方形中的最大值。同理,x i j 儲存第i行第jj n 1列的長方形中的最小值。這時再對這兩個陣列的每一列上的值進行維護,將x中每個區間的的最大值用y維護,將x中的每個區間的最小值用y維護。那麼y i j...