HDU 2888:Check Corners(二维RMQ)

Posted Shadowdsp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 2888:Check Corners(二维RMQ)相关的知识,希望对你有一定的参考价值。

http://acm.hdu.edu.cn/showproblem.php?pid=2888

题意:给出一个n*m的矩阵,还有q个询问,对于每个询问有一对(x1,y1)和(x2,y2),求这个子矩阵中的最大值,和判断四个角有没有等于这个最大值的。

思路:二维RMQ模板题。注意内存卡的挺紧的。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cmath>
 5 using namespace std;
 6 #define N 301
 7 int dp[N][N][9][9], mp[N][N], n, m, x1, x2, y11, y2;
 8 // 内存刚好 30704kB 卡着过了
 9 
10 void Init() {
11     for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) dp[i][j][0][0] = mp[i][j];
12     int A = (int)(log(n) / log(2)), B = (int)(log(m) / log(2));
13     for(int j = 0; j <= A; j++) {
14         for(int y = 0; y <= B; y++) {
15             if(j == 0 && y == 0) continue;
16             for(int i = 1; i + (1 << j) - 1 <= n; i++)
17                 for(int x = 1; x + (1 << y) - 1 <= m; x++)
18                     if(j) dp[i][x][j][y] = max(dp[i][x][j-1][y], dp[i+(1<<(j-1))][x][j-1][y]);
19                     else dp[i][x][j][y] = max(dp[i][x][j][y-1], dp[i][x+(1<<(y-1))][j][y-1]);
20         }
21     }
22 }
23 
24 int Query() {
25     int A = (int)(log(x2 - x1 + 1) / log(2)), B = (int)(log(y2 - y11 + 1) / log(2));
26     int a = dp[x1][y11][A][B];
27     int b = dp[x2-(1<<A)+1][y11][A][B];
28     int c = dp[x1][y2-(1<<B)+1][A][B];
29     int d = dp[x2-(1<<A)+1][y2-(1<<B)+1][A][B];
30     return max(a, max(b, max(c, d)));
31 }
32 
33 bool check(int val) {
34     if(mp[x1][y11] == val || mp[x2][y2] == val || mp[x1][y2] == val || mp[x2][y11] == val) return true;
35     return false;
36 }
37 
38 int main() {
39     while(~scanf("%d%d", &n, &m)) {
40         for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d", &mp[i][j]);
41         int q; scanf("%d", &q);
42         Init();
43         while(q--) {
44             scanf("%d%d%d%d", &x1, &y11, &x2, &y2);
45             int val = Query();
46             printf("%d ", val);
47             if(check(val)) puts("yes");
48             else puts("no");
49         }
50     }
51     return 0;
52 }

 

以上是关于HDU 2888:Check Corners(二维RMQ)的主要内容,如果未能解决你的问题,请参考以下文章

HDOJ 2888Check Corners(裸二维RMQ)

hdu2888 二维RMQ

获取二维数组的“角”

HDU2855—Fibonacci Check-up

[HDU2855]Fibonacci Check-up

[HDU] Fibonacci Check-up