zoukankan      html  css  js  c++  java
  • bzoj1047 理想的正方形

    Description

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

    Input

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

    Output

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

    水平方向用单调队列扫一次得出所有1*n区域的最大值和最小值

    竖直方向再用单调队列扫一次上一部记录的最大值和最小值得出所有n*n区域的最大值和最小值

    时间复杂度O(n2)

    #include<cstdio>
    int a,b,n,v[1024][1024];
    int mx1[1024][1024],mn1[1024][1024];
    int mx2[1024][1024],mn2[1024][1024];
    struct{
        int q[4096],qt[4096];
        int qs,qe;
        void clear(){
            qs=qe=0;
        }
        void push(int x,int t){
            while(qs<qe&&q[qe-1]<=x)--qe;
            qt[qe]=t;
            q[qe++]=x;
        }
        void chk(int p){
            while(qs<qe&&qt[qs]<=p)qs++;
        }
        int max(){
            return q[qs];
        }
    }q1;
    struct{
        int q[4096],qt[4096];
        int qs,qe;
        void clear(){
            qs=qe=0;
        }
        void push(int x,int t){
            while(qs<qe&&q[qe-1]>=x)--qe;
            qt[qe]=t;
            q[qe++]=x;
        }
        void chk(int p){
            while(qs<qe&&qt[qs]<=p)qs++;
        }
        int min(){
            return q[qs];
        }
    }q2;
    int main(){
        scanf("%d%d%d",&a,&b,&n);
        for(int i=0;i<a;i++)
        for(int j=0;j<b;j++)scanf("%d",v[i]+j);
        for(int i=0;i<a;i++){
            q1.clear();
            q2.clear();
            for(int j=0;j<n;j++)q1.push(v[i][j],j),q2.push(v[i][j],j);
            mx1[i][n-1]=q1.max();
            mn1[i][n-1]=q2.min();
            for(int j=n;j<b;j++){
                q1.push(v[i][j],j);
                q1.chk(j-n);
                mx1[i][j]=q1.max();
                q2.push(v[i][j],j);
                q2.chk(j-n);
                mn1[i][j]=q2.min();
            }
        }
        for(int j=0;j<b;j++){
            q1.clear();
            q2.clear();
            for(int i=0;i<n;i++)q1.push(mx1[i][j],i),q2.push(mn1[i][j],i);
            mx2[n-1][j]=q1.max();
            mn2[n-1][j]=q2.min();
            for(int i=n;i<a;i++){
                q1.push(mx1[i][j],i);
                q1.chk(i-n);
                mx2[i][j]=q1.max();
                q2.push(mn1[i][j],i);
                q2.chk(i-n);
                mn2[i][j]=q2.min();
            }
        }
        int minv=2147483647;
        for(int i=n-1;i<a;i++){
            for(int j=n-1;j<b;j++){
                if(mx2[i][j]-mn2[i][j]<minv)minv=mx2[i][j]-mn2[i][j];
            }
        }
        printf("%d",minv);
        return 0;
    }
  • 相关阅读:
    使用tcmalloc编译启动时宕机
    使用tcmalloc编译出现undefined reference to `sem_init'
    使用AddressSanitizer做内存分析(一)——入门篇
    VIM-美化你的标签栏
    Entity Framework Code First (六)存储过程
    Entity Framework Code First (五)Fluent API
    Entity Framework Code First (四)Fluent API
    Entity Framework Code First (三)Data Annotations
    Entity Framework Code First (二)Custom Conventions
    Entity Framework Code First (一)Conventions
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5136554.html
Copyright © 2011-2022 走看看