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;
    }
  • 相关阅读:
    Direct3D轮回:游戏场景之天空
    Direct3D轮回:游戏特效之晴天光晕
    Direct3D轮回:基于.X文件的网格加载及渲染
    Direct3D轮回:游戏特效之风动、雾化
    Direct3D轮回:游戏场景之陆地
    Direct3D轮回:基于ID3DXSprite的2D元素绘制
    Direct3D轮回:基于HLSL实现D3D中的光照特效
    Direct3D轮回:构建基于Direct3D的通用摄影机类
    Direct3D轮回:构建基于DirectInput机制的键盘输入设备
    剪切上传图片源码
  • 原文地址:https://www.cnblogs.com/2016gdgzoi471/p/9476894.html
Copyright © 2011-2022 走看看