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

[二维RMQ]luogu 2216 [HAOI2007]理想的正方形

时间:2019-03-01 22:19:02      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:cst   scan   printf   event   数据   style   can   i+1   ide   

题目描述

有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小。

输入输出格式

输入格式:

 

第一行为3个整数,分别表示a,b,n的值

第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。

 

输出格式:

 

仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值。

 

输入输出样例

输入样例
5 4 2
1 2 5 6
0 17 16 0
16 17 2 1
2 10 2 1
1 2 2 2
输出样例
1

说明

问题规模

(1)矩阵中的所有数都不超过1,000,000,000

(2)20%的数据2<=a,b<=100,n<=a,n<=b,n<=10

(3)100%的数据2<=a,b<=1000,n<=a,n<=b,n<=100

 

分析

暴力打法显然,设mx[i][j][k]为以i,j为左上角,边长为k的正方形的最大值(最小值同)

mx[i][j][k]=max(mx[i+1][j+1][k-1],mx[i+1][j][k-1],mx[i][j+1][k-1],rect[i][j])

然而O(1000^3)显然超

观察一下,我们发现这个东西很像一个二维的RMQ,那么改一下

mx[i][j][k]为以i,j为左上角,边长为2^k的正方形的最大值

mx[i][j][k]=max(mx[i+2^(k-1)][j+2^(k-1)][k-1],mx[i+2^(k-1)][j][k-1],mx[i][j+2^(k-1][k-1],mx[i][j][k-1])

统计也差不多,注意补一下不满的二进制位和边界

 

技术图片
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int N=1e3+10;
int mx[N][N],mn[N][N];
int a,b,n,logn;

int Get_Ans(int i,int j) {
    int mxx=0,mnn=2147483647;
    mxx=max(mx[i][j],max(mx[i+n-(1<<logn)][j],max(mx[i][j+n-(1<<logn)],mx[i+n-(1<<logn)][j+n-(1<<logn)])));
    mnn=min(mn[i][j],min(mn[i+n-(1<<logn)][j],min(mn[i][j+n-(1<<logn)],mn[i+n-(1<<logn)][j+n-(1<<logn)])));
    return mxx-mnn;
}

int main() {
    scanf("%d%d%d",&a,&b,&n);
    for (int i=1;i<=a;i++)
        for (int j=1;j<=b;j++) {
            scanf("%d",&mx[i][j]);
            mn[i][j]=mx[i][j];
        }
    logn=log(n)/log(2);
    for (int k=1;k<=logn;k++)
        for (int i=1;i<=a-(1<<k-1);i++)
            for (int j=1;j<=b-(1<<k-1);j++)
                mx[i][j]=max(mx[i][j],max(mx[i+(1<<k-1)][j],max(mx[i][j+(1<<k-1)],mx[i+(1<<k-1)][j+(1<<k-1)]))),
                mn[i][j]=min(mn[i][j],min(mn[i+(1<<k-1)][j],min(mn[i][j+(1<<k-1)],mn[i+(1<<k-1)][j+(1<<k-1)])));
    int ans=2147483647;
    for (int i=1;i<=a-n+1;i++)
        for (int j=1;j<=b-n+1;j++)
            ans=min(ans,Get_Ans(i,j));
    printf("%d",ans);
}
View Code

 

[二维RMQ]luogu 2216 [HAOI2007]理想的正方形

标签:cst   scan   printf   event   数据   style   can   i+1   ide   

原文地址:https://www.cnblogs.com/mastervan/p/10459022.html

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