zoukankan      html  css  js  c++  java
  • bzoj1047-理想的正方形(二维单调队列)

    题意: 给一个矩阵,给出行列和每个数,再给出一个N,求出所有N*N的子矩阵中最大值最小值之差的最小值
    解析: 暴力枚举肯定不行,这题可以用二维单调队列做,把同一行的连续N个点缩成一个点保存最大最小值预处理
    ,用单调队列即可实现,再对整个矩阵进行枚举,再用一次单调队列。

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    using namespace std;
    const int INF=1e9+7;
    const int maxn=1002;
    int row,col,N;
    int A[maxn][maxn];
    int Min[maxn][maxn],Max[maxn][maxn];
    int q1[maxn],q2[maxn];
    int f1,f2,r1,r2;
    void init() //预处理
    {
        for(int i=1;i<=row;i++)
        {
            f1=1,r1=0;
            f2=1,r2=0;
            for(int j=1;j<N;j++)
            {
                while(r1>=f1&&A[i][q1[r1]]>=A[i][j]) r1--;
                q1[++r1]=j;
                while(r2>=f2&&A[i][q2[r2]]<=A[i][j]) r2--;
                q2[++r2]=j;
            }
            for(int j=N;j<=col;j++)
            {
                while(r1>=f1&&A[i][q1[r1]]>=A[i][j]) r1--;
                q1[++r1]=j;
                while(q1[f1]+N<=j) f1++;
                Min[i][j-N+1]=A[i][q1[f1]]; //缩点后的最小值
    
                while(r2>=f2&&A[i][q2[r2]]<=A[i][j]) r2--;
                q2[++r2]=j;
                while(q2[f2]+N<=j) f2++;
                Max[i][j-N+1]=A[i][q2[f2]]; //缩点后的最大值
            }
        }
    }
    int solve()
    {
        int ret=INF;
        for(int j=1;j+N-1<=col;j++) //对同一列进行枚举
        {
            f1=1,r1=0;
            f2=1,r2=0;
            int minv=INF,maxv=-INF;
            for(int i=1;i<N;i++)
            {
                while(r1>=f1&&Min[q1[r1]][j]>=Min[i][j]) r1--;
                q1[++r1]=i;
                while(r2>=f2&&Max[q2[r2]][j]<=Max[i][j]) r2--;
                q2[++r2]=i;
            }
            for(int i=N;i<=row;i++)
            {
                while(r1>=f1&&Min[q1[r1]][j]>=Min[i][j]) r1--;
                q1[++r1]=i;
                while(q1[f1]+N<=i) f1++;
                minv=Min[q1[f1]][j];
                while(r2>=f2&&Max[q2[r2]][j]<=Max[i][j]) r2--;
                q2[++r2]=i;
                while(q2[f2]+N<=i) f2++;
                maxv=Max[q2[f2]][j];
                ret=min(ret,maxv-minv);
            }
        }
        return ret;
    }
    int main()
    {
        scanf("%d%d%d",&row,&col,&N);
        for(int i=1;i<=row;i++)
            for(int j=1;j<=col;j++) scanf("%d",&A[i][j]);
        init();
        printf("%d
    ",solve());
        return 0;
    }
    View Code
  • 相关阅读:
    Individual Method Selection Survey rubric
    Xcode 出现Thread 1: signal SIGABRT
    C/C++生成随机数
    《深入浅出深度学习:原理剖析与python实践》第八章前馈神经网络(笔记)
    操作系统--精髓与设计原理(第八版)第三章复习题答案
    操作系统--精髓与设计原理(第八版)第二章复习题答案
    Python知识点整理
    C++ <queue>用法
    C语言结构体用法
    Mac安装Qt出现错误Could not resolve SDK Path for 'macosx'
  • 原文地址:https://www.cnblogs.com/wust-ouyangli/p/5809483.html
Copyright © 2011-2022 走看看