Check Corners HDU - 2888(二维RMQ)

就是板题。。

查询子矩阵中最大的元素。。。然后看看是不是四个角落的  是就是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;
}

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

时间: 2024-10-25 12:07:10

Check Corners HDU - 2888(二维RMQ)的相关文章

【HDOJ 2888】Check Corners(裸二维RMQ)

Problem Description Paul draw a big m*n matrix A last month, whose entries Ai,j are all integer numbers ( 1 <= i <= m, 1 <= j <= n ). Now he selects some sub-matrices, hoping to find the maximum number. Then he finds that there may be more tha

HDU 2888:Check Corners 二维RMQ

Check Corners 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2888 题意: 求矩形区间内的最大值 题解: 二维RMQ,和一维的区别不大,按一维的做法求出每一行上的RMQ,再处理行与行之间的关系就好了. 代码 #include<stdio.h> const int N=301; const int M=301; int dp[N][M][9][9]; int mmax(int x,int y) { return x>y?x:

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

HDU2888 Check Corners(二维RMQ)

有一个矩阵,每次查询一个子矩阵,判断这个子矩阵的最大值是不是在这个子矩阵的四个角上 裸的二维RMQ 1 #pragma comment(linker, "/STACK:1677721600") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8

HDU 2069二维母函数

显然母函数,有一个地方需要注意.当输入0时,只有一种方法,所以输出1. 代码: 1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 int c1[255][111], c2[255][111]; 7 main() 8 { 9 10 int n, i, j, k, l; 11 int a[

【bzoj1047】[HAOI2007]理想的正方形 二维RMQ

题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数.每行相邻两数之间用一空格分隔.100%的数据2<=a,b<=1000,n<=a,n<=b,n<=1000 输出 仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值. 样例输入 5 4 2 1 2 5 6 0 1

[hdu2888]二维RMQ

题意:求矩形内最大值.二维RMQ. 1 #pragma comment(linker, "/STACK:10240000,10240000") 2 3 #include <iostream> 4 #include <cstdio> 5 #include <algorithm> 6 #include <cstdlib> 7 #include <cstring> 8 #include <map> 9 #include

Cornfields poj2019 二维RMQ

Cornfields Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Submit Status Description FJ has decided to grow his own corn hybrid in order to help the cows make the best possible milk. To that end, he's looking to build the

P2216 [HAOI2007]理想的正方形(二维RMQ)

题目描述 有一个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