zoukankan      html  css  js  c++  java
  • 【bzoj1047】[HA蛤OI2007]理想的正方形【单调队列】

    题目传送门
    xfz学长给我们讲了单调栈和单调队列,这方面内容以前写过PJT4的跳房子等等。
    事实上单调栈和单调队列挺好理解的,单调栈是栈内元素单调的栈,单调队列是队内元素单调的队列(废话)
    先写一道非常裸的模板题。这道题以最大值为例,先一次单调队列求出每一行每个位置向右连续n个数的最大值,再一次单调队列把之前求出的一维最大值用同样的方法和并为二维最大值。单调队列实现方法就是先把左端点不在当前考虑区间内的丢掉,再比较当前位置与队尾的大小,若大于等于则把队尾丢掉,把当前位置的元素放进去。求出最大值和最小值最后统计即可。细节详见代码。(其实没啥细节,我这样的菜鸡也能1A)

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=1005;
    int n,m,x,head,tail,ans=1e9,q[N],a[N][N],f[N][N],maxn[N][N],minn[N][N];
    int main(){
        scanf("%d%d%d",&n,&m,&x);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%d",&a[i][j]);
            }
        }
        for(int i=1;i<=n;i++){
            head=1,tail=0;
            for(int j=1;j<=x;j++){
                while(head<=tail&&a[i][j]>=a[i][q[tail]]){
                    tail--;
                }
                q[++tail]=j;
            }
            f[i][1]=a[i][q[head]];
            for(int j=x+1;j<=m;j++){
                while(head<=tail&&q[head]<j-x+1){
                    head++;
                }
                while(head<=tail&&a[i][j]>=a[i][q[tail]]){
                    tail--;
                }
                q[++tail]=j;
                f[i][j-x+1]=a[i][q[head]];
            }
        }
        for(int i=1;i<=m-x+1;i++){
            head=1,tail=0;
            for(int j=1;j<=x;j++){
                while(head<=tail&&f[j][i]>=f[q[tail]][i]){
                    tail--;
                }
                q[++tail]=j;
            }
            maxn[1][i]=f[q[head]][i];
            for(int j=x+1;j<=n;j++){
                while(head<=tail&&q[head]<j-x+1){
                    head++;
                }
                while(head<=tail&&f[j][i]>=f[q[tail]][i]){
                    tail--;
                }
                q[++tail]=j;
                maxn[j-x+1][i]=f[q[head]][i];
            }
        }
        for(int i=1;i<=n;i++){
            head=1,tail=0;
            for(int j=1;j<=x;j++){
                while(head<=tail&&a[i][j]<=a[i][q[tail]]){
                    tail--;
                }
                q[++tail]=j;
            }
            f[i][1]=a[i][q[head]];
            for(int j=x+1;j<=m;j++){
                while(head<=tail&&q[head]<j-x+1){
                    head++;
                }
                while(head<=tail&&a[i][j]<=a[i][q[tail]]){
                    tail--;
                }
                q[++tail]=j;
                f[i][j-x+1]=a[i][q[head]];
            }
        }
        for(int i=1;i<=m-x+1;i++){
            head=1,tail=0;
            for(int j=1;j<=x;j++){
                while(head<=tail&&f[j][i]<=f[q[tail]][i]){
                    tail--;
                }
                q[++tail]=j;
            }
            minn[1][i]=f[q[head]][i];
            for(int j=x+1;j<=n;j++){
                while(head<=tail&&q[head]<j-x+1){
                    head++;
                }
                while(head<=tail&&f[j][i]<=f[q[tail]][i]){
                    tail--;
                }
                q[++tail]=j;
                minn[j-x+1][i]=f[q[head]][i];
            }
        }
        for(int i=1;i<=n-x+1;i++){
            for(int j=1;j<=m-x+1;j++){
                ans=min(ans,maxn[i][j]-minn[i][j]);
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Redis学习之一--基础知识
    工作流学习之--TPFlow数据库分析
    什么是域名?什么网站名?什么是URL
    SASS的升级版--SCSS 基本介绍+Sass使用详解
    vue调试工具vue-devtools的安装(win10系统,最新2020年6月的解决方案)
    如何运行vue项目
    用WebStorm搭建vue项目
    Terminal怎么停止VUE项目
    VUE 在一个组件中引用另外一个组件的两种方式
    Vue.js——60分钟快速入门 开发· webpack 中文文档
  • 原文地址:https://www.cnblogs.com/2016gdgzoi471/p/9476894.html
Copyright © 2011-2022 走看看