当前位置: 首页 > news >正文

hdu 2888 Check Corners

二维RMQ

题意:给一个n*m的矩阵,下面q的询问,每个询问给出一个子矩阵的左上角和右下角的坐标,要你求出这个子矩阵里面的最大元素,然后输出,并且,这个最大元素和子矩阵的四个角上的元素比较,只要能和其中一个元素相等,就输出yes,否则输出no

一维RMQ的ST算法,是叫一段2^i长度的序列分成两个2^(i-1)的序列然后计算。二维的RMQ依然使用ST的DP思想,不过对于一个矩形,将其分成完全相等的4个部分,然后求最值,特殊情况是,当一个子矩阵的宽为1,即在宽上不能二分的时候,已经长为1,即长不能二分的时候,其实就是一个一维的RMQ,我是采用了单独处理的方法(我把它归为初始化的一部分),而对于一般情况,就是普通的DP了

查询也是一样的,和一维的查询思想相同,也是将要查询的矩阵分成4份,允许有覆盖部分的去查询

 

思想不难的,代码量多了而已,注意细节,另外空间比较那个,会超空间,只要数组在够用的情况下尽可能小就可以了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define N 305
#define M 11
#define INF 0x3f3f3f3f

int row,col;
int __pow[M];
int dp[N][M][N][M];
int a[N][N];

bool check(int res , int r1 , int c1 , int r2 , int c2)
{
    if(res == a[r1][c1] || res == a[r1][c2] || res == a[r2][c1] || res == a[r2][c2]) return true;
    return false;
}

inline int max(int aa ,int bb ,int cc ,int dd)
{
    int res = -INF;
    res = aa > res ? aa : res;
    res = bb > res ? bb : res;
    res = cc > res ? cc : res;
    res = dd > res ? dd : res;
    return res;
}

void ST()
{
    int KR = (int)(log((double)row) / log(2.0));
    int KC = (int)(log((double)col) / log(2.0));
    for(int i=1; i<=row; i++)            //初始化dp[i][0][j][0]
        for(int j=1; j<=col; j++)
            dp[i][0][j][0] = a[i][j];
    for(int i=1; i<=row; i++)           //初始化dp[i][0][j][p]
        for(int pc=1; pc<=KC; pc++)
            for(int j=1; j+__pow[pc]-1<=col; j++)
            {
                int kc = j + __pow[pc-1];
                int x = dp[i][0][j][pc-1] , y = dp[i][0][kc][pc-1];
                dp[i][0][j][pc] = x > y ? x : y;
            }
    for(int j=1; j<=col; j++)           //初始化dp[i][p][j][0]
        for(int pr=1; pr<=KR; pr++)
            for(int i=1; i+__pow[pr]-1<=row; i++)
            {
                int kr = i + __pow[pr-1];
                int x = dp[i][pr-1][j][0] , y = dp[kr][pr-1][j][0];
                dp[i][pr][j][0] = x > y ? x : y;
            }
    for(int pr=1; pr<=KR; pr++) 
        for(int pc=1; pc<=KC; pc++)
            for(int i=1; i+__pow[pr]-1<=row; i++)
                for(int j=1; j+__pow[pc]-1<=col; j++)
                {
                    int kr = i + __pow[pr-1];
                    int kc = j + __pow[pc-1];
                    dp[i][pr][j][pc] = max(dp[i][pr-1][j][pc-1] , dp[i][pr-1][kc][pc-1] , dp[kr][pr-1][j][pc-1] , dp[kr][pr-1][kc][pc-1]);
                }
}

int RMQ(int r1 , int c1 , int r2 , int c2)
{
    int KR = (int)(log((double)(r2-r1+1)) / log(2.0));
    int KC = (int)(log((double)(c2-c1+1)) / log(2.0));
    int kr = r2 - __pow[KR] + 1;
    int kc = c2 - __pow[KC] + 1;
    return max(dp[r1][KR][c1][KC] , dp[r1][KR][kc][KC] , dp[kr][KR][c1][KC] , dp[kr][KR][kc][KC]);
}

int main()
{
    for(int i=0; i<M; i++) __pow[i] = (1<<i);
    while(scanf("%d%d",&row,&col)!=EOF)
    {
        for(int i=1; i<=row; i++)
            for(int j=1; j<=col; j++)
                scanf("%d",&a[i][j]);
        ST();
        int q;
        scanf("%d",&q);
        while(q--)
        {
            int ok = 0,r1,c1,r2,c2;
            scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
            int res = RMQ(r1,c1,r2,c2);
            printf("%d ",res);
            if(check(res ,r1,c1,r2,c2)) printf("yes\n");
            else                        printf("no\n");
        }
    }
    return 0;
}

 

相关文章:

  • Android tabHost 刷新Activity
  • 测试在CENTOS X64 6.2 上安装ORACLE 11g client
  • function类html5游戏开发-零基础开发《圣诞老人送礼物》小游戏
  • 3G美餐:谁有红苹果?
  • .NET中 MVC 工厂模式浅析
  • Hyper-V 2节点集群高可用的限制
  • 记几个IOS工具网站
  • MIME邮件面面观
  • CentOS 6.3(x86_32)下安装Oracle 10g R2
  • lsof命令的使用
  • linux0.11学习笔记(2)
  • C#基本数据类型 思维导图
  • android FM播放时拔出耳机后,FM APP出现拔出耳机,Fm停止的提示框,然后自动close...
  • 编写shell脚本的另一种方法
  • 《CLR via C#》 之运行时序列化(3)
  • (三)从jvm层面了解线程的启动和停止
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • Django 博客开发教程 16 - 统计文章阅读量
  • download使用浅析
  • express + mock 让前后台并行开发
  • express.js的介绍及使用
  • JS题目及答案整理
  • LeetCode18.四数之和 JavaScript
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • ng6--错误信息小结(持续更新)
  • node学习系列之简单文件上传
  • PAT A1120
  • WebSocket使用
  • 数据仓库的几种建模方法
  • 数据结构java版之冒泡排序及优化
  • 突破自己的技术思维
  • 一个项目push到多个远程Git仓库
  • 湖北分布式智能数据采集方法有哪些?
  • ​一些不规范的GTID使用场景
  • # 安徽锐锋科技IDMS系统简介
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • $NOIp2018$劝退记
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • ()、[]、{}、(())、[[]]命令替换
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (接口封装)
  • (十)T检验-第一部分
  • (实战篇)如何缓存数据
  • (太强大了) - Linux 性能监控、测试、优化工具
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET CLR基本术语
  • .Net的DataSet直接与SQL2005交互
  • .php文件都打不开,打不开php文件怎么办
  • /proc/stat文件详解(翻译)
  • @CacheInvalidate(name = “xxx“, key = “#results.![a+b]“,multi = true)是什么意思
  • [asp.net core]project.json(2)
  • [C++]指针与结构体
  • [CTF]2022美团CTF WEB WP
  • [C语言]一维数组二维数组的大小