【bzoj1047】理想的正方形

题意

给定\(a*b\)由整数组成的矩形。

现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值

的差最小。

\(1\leq a,b\leq 1000\)

\(1\leq n\leq 100\)

分析

枚举每一个位置,然后考虑快速求矩形内的最大值和最小值即可。

单调队列可以快速实现:

先求出\(d[i][j]\)表示\(a[i][j-n+1,j-n,...,j]\)中的最值。

然后求出\(f[i][j]\)表示\(d[i-n+1,i-n,...,i][j]\)中的最值。

所有的\(f[i][j]\)就表示以\((i,j)\)为右下角端点的矩形的最值。

也可以使用ST表。

由于\(n\)一定,所以只需要用一个简化的二维ST表即可。

\(f[i][j][k]\)表示跨度为\(2^i\),终点在\((j,k)\)的矩形的最值。

注意ST表的正确姿势。

对于二维ST表,记\(f[i][j][k][l]\),其中两个跨度放前面。

不然调试起来会很麻烦的。

代码

#include <cstdio>
#include <cctype>
#include <cmath>
#include <climits>
#include <algorithm>
using namespace std;

#define rep(i,a,b) for (int i=(a);i<=(b);i++)

const int N=1001;
const int U=10;

const int MAX=INT_MAX>>1;
const int MIN=INT_MIN>>1;

int n,m,siz;
int a[N][N];

int un,um; int unit;
int maxV[U][N][N],minV[U][N][N];
int res;

int rd(void) {
    int x=0,f=1; char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}

int Query(int x,int y) {
    int tx=(x-siz+1)+(1<<unit)-1;
    int ty=(y-siz+1)+(1<<unit)-1;

    int mx=MIN;
    mx=max(mx,maxV[unit][x][y]);
    mx=max(mx,maxV[unit][x][ty]);
    mx=max(mx,maxV[unit][tx][y]);
    mx=max(mx,maxV[unit][tx][ty]);

    int mn=MAX;
    mn=min(mn,minV[unit][x][y]);
    mn=min(mn,minV[unit][x][ty]);
    mn=min(mn,minV[unit][tx][y]);
    mn=min(mn,minV[unit][tx][ty]);

    return mx-mn;
}

int main(void) {
    #ifndef ONLINE_JUDGE
    freopen("bzoj1047.in","r",stdin);
    freopen("bzoj1047.out","w",stdout);
    #endif

    n=rd(),m=rd(),siz=rd();
    rep(i,1,n) rep(j,1,m)
        a[i][j]=rd();

    unit=(int)(log(siz)/log(2));
    rep(i,0,unit) rep(j,1,n) rep(k,1,m) {
        minV[i][j][k]=MAX;
        maxV[i][j][k]=MIN;
    }
    rep(j,1,n) rep(k,1,m) {
        minV[0][j][k]=a[j][k];
        maxV[0][j][k]=a[j][k];
    }
    rep(i,1,unit) rep(j,1,n) rep(k,1,m) {
        int tj=max(1,j-(1<<(i-1)));
        int tk=max(1,k-(1<<(i-1)));

        int *now=&(minV[i][j][k]);
        *now=min(*now,minV[i-1][j][k]);
        *now=min(*now,minV[i-1][j][tk]);
        *now=min(*now,minV[i-1][tj][k]);
        *now=min(*now,minV[i-1][tj][tk]);

        now=&(maxV[i][j][k]);
        *now=max(*now,maxV[i-1][j][k]);
        *now=max(*now,maxV[i-1][j][tk]);
        *now=max(*now,maxV[i-1][tj][k]);
        *now=max(*now,maxV[i-1][tj][tk]);
    }

    res=MAX;
    rep(i,siz,n) rep(j,siz,m) {
        int t=Query(i,j);
        res=min(res,t);
    }
    printf("%d\n",res);

    return 0;
}

【bzoj1047】理想的正方形的更多相关文章

  1. bzoj1047理想的正方形

    题目链接 纪念又双叒叕的一道暴力碾标算的题 我们考虑纯暴力 #include<iostream> #include<cstdio> #include<algorithm& ...

  2. bzoj1047 理想的正方形

    Description 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. Input 第一行为3个整数,分别表示a,b,n的值第二行至第 ...

  3. 【BZOJ1047】[HAOI2007]理想的正方形(单调队列,动态规划)

    [BZOJ1047][HAOI2007]理想的正方形(单调队列,动态规划) 题面 BZOJ 洛谷 题解 直接一个单调队列维护一下没给点和它前面的\(n\)个位置的最大值,再用一次单调队列维护连续\(n ...

  4. 【BZOJ1047】[HAOI2007]理想的正方形

    [BZOJ1047][HAOI2007]理想的正方形 题面 bzoj 洛谷 题解 二维\(st\)表,代码是以前的 #include<iostream> #include<cstdi ...

  5. [bzoj1047][HAOI2007]理想的正方形_动态规划_单调队列

    理想的正方形 bzoj-1047 HAOI-2007 题目大意:有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 注释:$2\le a, ...

  6. BZOJ1047: [HAOI2007]理想的正方形 [单调队列]

    1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2857  Solved: 1560[Submit][St ...

  7. bzoj千题计划215:bzoj1047: [HAOI2007]理想的正方形

    http://www.lydsy.com/JudgeOnline/problem.php?id=1047 先用单调队列求出每横着n个最大值 再在里面用单调队列求出每竖着n个的最大值 这样一个位置就代表 ...

  8. 【BZOJ1047】[HAOI2007]理想的正方形 (倍增ST表)

    [HAOI2007]理想的正方形 题目描述 有一个\(a*b\)的整数组成的矩阵,现请你从中找出一个\(n*n\)的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: ...

  9. HAOI2007 理想的正方形

    1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1402  Solved: 738[Submit][Sta ...

随机推荐

  1. Storm系列之三——Fault Tolerance

    本文介绍Storm容错的设计细节. 1.当一个worker进程死了会发生什么? 当worker死了,supervisor会重启它.如果它尝试开启多次失败并且不能与nimbus发送心跳,Nimbus会重 ...

  2. Ghostscript命令实践

    一. 将单张PDF文件igs.pdf转化为tiff文件. . gs -sDEVICE=tiffg4 -sOutputFile=igs.tiff -dMaxStripSize= igs.pdf -dAd ...

  3. 青岛理工大学第五届ACM交流赛 部分题解

    A:后缀维护si*pi的最小值,查询的时候二分,判断后缀和当前两个部分就行. #include <bits/stdc++.h> using namespace std; typedef l ...

  4. [SAP ABAP开发技术总结]RETURN、STOP、EXIT、CHECK、LEAVE、REJECT

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. [SAP ABAP开发技术总结]ALV

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  6. python 自动生成C++代码 (代码生成器)

    python 代码自动生成的方法 (代码生成器) 遇到的问题 工作中遇到这么一个事,需要写很多C++的底层数据库类,但这些类大同小异,无非是增删改查,如果人工来写代码,既费力又容易出错:而借用pyth ...

  7. 中国用户mac上快速安装nodejs

    mac nodejs 安装 1.http://npm.taobao.org/mirrors/node/latest/ 进入这个域名,然后找到最新的pkg包下载过来 2.双击pkg包,下一步下一步安装 ...

  8. HDU 1698 Just a Hook(线段树成段更新)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  9. GATK3.2.2小结(转载)

    http://blog.csdn.net/skenoy/article/details/38346489 经过几天的摸索和网上资料的查询对GATK软件有点小心得,现总结如下: 1. fasta文件最好 ...

  10. iOS - Swift Subscript 下标脚本

    1.Subscript 下标脚本允许你通过在实例后面的方括号中传入一个或者多个的索引值来对实例进行访问和赋值.语法类似于实例方法和计算型属性的混合.与定义实例方法类似,定义下标脚本使用 subscri ...