B1047 理想的正方形 RMQ

2022-03-13 06:03:08 字數 3265 閱讀 9493

大家吸取我的教訓,想好再寫。我碼了好長時間,最後發現演算法處理的是另乙個問題,我處理的是正方形情況的,才能用我優化之後的記憶化搜尋,然而矩形就涼了。

先看一下題吧:

description

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

的差最小。

input

第一行為3個整數,分別表示a,b,n的值第二行至第a+1行每行為b個非負整數,表示矩陣中相應位置上的數。每

行相鄰兩數之間用一空格分隔。

100%的資料2<=a,b<=1000,n<=a,n<=b,n<=1000

output

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

sample input54

2125

601716016

17212

10211

222sample output

1hint

source

我的反面教材**:

#include#include

#include

#include

#include

#include

#include

using

namespace

std;

#define duke(i,a,n) for(int i = a;i <= n;i++)

#define lv(i,a,n) for(int i = a;i >= n;i--)

#define clean(a) memset(a,0,sizeof(a))

const

int inf = 1

<< 30

;typedef

long

long

ll;typedef

double

db;template

void read(t &x)

template

void

write(t x)

inta,b,n;

int p[1010][1010

];int f[1010][1010][15][3

];int l[15

];void dfs(int o,int x1,int y1,int x2,int

y2)

int minn =inf;

int maxn = 0

; dfs(o + 1,x1,y1,x1 + l[o],y1 +l[o]);

dfs(o + 1,a - l[o],y1,a,y1 +l[o]);

dfs(o + 1,x1,b - l[o],x1 +l[o],b);

dfs(o + 1,a - l[o],b -l[o],a,b);

//printf("%d %d %d %d\n",a - l[o],b - l[o],a,b);

maxn = max(maxn,f[x1][y1][o + 1][1

]); minn = min(minn,f[x1][y1][o + 1][0

]); maxn = max(maxn,f[a - l[o]][y1][o + 1][1

]); minn = min(minn,f[a - l[o]][y1][o + 1][0

]); maxn = max(maxn,f[x1][b - l[o]][o + 1][1

]); minn = min(minn,f[x1][b - l[0]][o + 1][0

]); maxn = max(maxn,f[a - l[o]][b - l[o]][o + 1][1

]); minn = min(minn,f[a - l[o]][b - l[o]][o + 1][0

]); f[x1][y1][o][

1] =maxn;

f[x1][y1][o][

0] =minn;

return;}

intmain()

int k = n,len = 0

;

while(k > 1

)

duke(i,

1,a -n)

duke(j,

1,b -n)

dfs(

1,i,j,i + n,j +n);

printf(

"%d %d\n

",f[1][1][1][1],f[1][1][1][0

]);

return0;

}/*5 4 2

1 2 5 6

0 17 16 0

16 17 2 1

2 10 2 1

1 2 2 2

*/

然後就涼了,懶得寫了,用二維的rmq搞一下,抄了個比較清晰的**。。。

#include#include

#include

#include

using

namespace

std;

const

int inf = 1000000000

;const

int maxm = 1000 + 100

;const

int maxn = 100 + 10

;const

int maxlog = 10

;int

a, b, n;

intlogn;

intgrid[maxm][maxm];

intmaxv[maxm][maxm], minv[maxm][maxm];

int query (int x, int

y)int

main ()

for (logn = 0; ((1

<<(logn+1)) <= n); logn++);

for (int k = 0; k < logn; k++)

for (int i = 0; i+(1

<)

for (int j = 0; j+(1

<)

int ans =inf;

for (int i = 0; i <= a-n; i++)

for (int j = 0; j <= b-n; j++)

ans =min(ans, query(i, j));

cout

}

唉,後悔啊。。。

BZOJ1047 理想的正方形

time limit 10 sec memory limit 162 mb submit 4137 solved 2326 有乙個a b的整數組成的矩陣,現請你從中找出乙個n n的正方形區域,使得該區域所有數中的最大值和最小值 的差最小。第一行為3個整數,分別表示a,b,n的值第二行至第a 1行每行...

BZOJ 1047 理想的正方形

bzoj 1047 傳送門 1 先橫向用單調佇列求出每個數左邊 n 個數中的最值 2 再縱向利用橫向的結果用單調佇列進行相同的操作 通過以上操作將 a b 的矩陣轉化為了 a n 1 b n 1 的矩陣 相當於每個正方形被縮成了乙個點,而每個點的最值就代表著原正方形中的最值 tip 1 又被 1 2...

BZOJ 1047 理想的正方形

看到這到題,第一反應當然是暴搜一遍,但是資料較大,暴搜鐵定過不了,自然想到進行優化,優化的方案很多,每個人的思路可能不同,在這裡我的思路僅供參考。我的想法是用單調佇列 單調棧,當然簡單的單調佇列 單調棧只適用於一行資料,對於這道題要進行一定的組合和變換。根據題目的介紹,可以大致總結出以下資訊 第一,...