zoukankan      html  css  js  c++  java
  • bzoj:1047: [HAOI2007]理想的正方形

    Description

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

    Input

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

    Output

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

    Sample Input

    5 4 2
    1 2 5 6
    0 17 16 0
    16 17 2 1
    2 10 2 1
    1 2 2 2

    Sample Output

    1
     
     
     
    单调队列维护(i,j)在这一行往前n个位置的最大值和最小值,最后再单调队列统计一下就好啦
    #include<cstdio>
    #include<algorithm>
    using namespace std;
     
    int a,b,n,map[1001][1001],la[1001][1001],li[1001][1001],q[1001],num[1001],w[1001],nm[1001],fi,len,fw,lw,ans=1000000001,o,p;
    inline int read(){
        p=0;o=getchar();
        while(o<'0'||o>'9') o=getchar();
        while(o>='0'&&o<='9') p=p*10+o-48,o=getchar();
        return p;
    }
    inline int max(int x,int y){return x>y?x:y;}
    int main(){
        register int i,j;
        a=read();b=read();n=read();
        for (i=1;i<=a;i++)
        for (j=1;j<=b;j++) map[i][j]=read();
        for (i=1;i<=a;i++){
            fi=1;len=0;
            for (j=1;j<=b;j++){
                while ((len>=fi)&&(q[len]<=map[i][j])) len--;
                q[++len]=map[i][j];
                num[len]=j;
                while(num[fi]<=j-n) fi++;
                la[i][j]=q[fi];
            }
        }
        for (i=1;i<=a;i++){
            fi=1;len=0;
            for (j=1;j<=b;j++){
                while ((len>=fi)&&(q[len]>=map[i][j])) len--;
                q[++len]=map[i][j];
                num[len]=j;
                while(num[fi]<=j-n) fi++;
                li[i][j]=q[fi];
            }
        }
        for (j=n;j<=b;j++){
            fi=fw=1;len=lw=0;
            for (i=1;i<=a;i++){
                while((len>=fi)&&(q[len]<=la[i][j])) len--;
                q[++len]=la[i][j];
                num[len]=i;
                while(num[fi]<=i-n) fi++;
                while((lw>=fw)&&(w[lw]>=li[i][j])) lw--;
                w[++lw]=li[i][j];
                nm[lw]=i;
                while(nm[fw]<=i-n) fw++;
                if (i>=n) ans=min(q[fi]-w[fw],ans);
            }
        }
        printf("%d
    ",ans);
    }
  • 相关阅读:
    操作系统(32-45)
    异或运算( ^ )
    计算机网络(16—30)
    操作系统(13-30)
    win7 linux双系统删除linux
    ubuntu安装matplotlib包
    vmware+CentOS 7 无法上网
    Python命令行清屏的简单办法
    jupyter notebook 工作目录修改
    ipython notebook设置工作路径和自动保存.py文件 ipython_notebook_config.py
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5121144.html
Copyright © 2011-2022 走看看