码迷,mamicode.com
首页 > 其他好文 > 详细

Check Corners HDU - 2888(二维RMQ)

时间:2018-08-09 19:31:50      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:ems   ==   signed   names   base   name   inf   ons   for   

就是板题。。

查询子矩阵中最大的元素。。。然后看看是不是四个角落的  是就是yes  不是就是no  判断一下就好了

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 301, INF = 0x7fffffff;
int n, m;
int dp[maxn][maxn][9][9], a[maxn][maxn];

int rmq(int x1, int y1, int x2, int y2)
{

    int kx = 0, ky = 0;
    while ((1 << (1 + kx)) <= x2 - x1 + 1) kx++;
    while ((1 << (1 + ky)) <= y2 - y1 + 1) ky++;
    int m1 = dp[x1][y1][kx][ky];
    int m2 = dp[x2 - (1 << kx) + 1][y1][kx][ky];
    int m3 = dp[x1][y2 - (1 << ky) + 1][kx][ky];
    int m4 = dp[x2 - (1 << kx) + 1][y2 - (1 << ky) + 1][kx][ky];

    return max(max(m1, m2), max(m3, m4));

}

int main()
{
    while(cin>> n >> m)
    {
        rap(i, 1, n)
            rap(j, 1, m)
            {
                scanf("%d", &a[i][j]);
                dp[i][j][0][0] = a[i][j];
            }
        for (int i = 0; (1 << i) <= n; i++) {
            for (int j = 0; (1 << j) <= m; j++) {
                if (i == 0 && j == 0) continue;
                for (int row = 1; row + (1 << i) - 1 <= n; row++)
                    for (int col = 1; col + (1 << j) - 1 <= m; col++) {
                        //当x或y等于0的时候,就相当于一维的RMQ了
                        //if(i == 0) dp[row][col][i][j] = max(dp[row][col][i][j - 1], dp[row][col + (1 << (j - 1))][i][j - 1]);
                        if (j == 0) dp[row][col][i][j] = max(dp[row][col][i - 1][j], dp[row + (1 << (i - 1))][col][i - 1][j]);
                        else dp[row][col][i][j] = max(dp[row][col][i][j - 1], dp[row][col + (1 << (j - 1))][i][j - 1]);
                    }
            }
        }
        int q;
        scanf("%d", &q);
        while(q--)
        {
            int x1, y1, x2, y2;
            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
            int h = rmq(x1, y1, x2, y2);
            int flag = 0;
            if(a[x1][y1] == h || a[x2][y2] == h || a[x1][y2] == h || a[x2][y1] == h)
                flag = 1;
            printf("%d %s\n", h, flag?"yes":"no");
        }
    }

    return 0;
}

 

Check Corners HDU - 2888(二维RMQ)

标签:ems   ==   signed   names   base   name   inf   ons   for   

原文地址:https://www.cnblogs.com/WTSRUVF/p/9450927.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!