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

    我是题面

    题意挺清晰的,做法也挺简单的

    用单调队列维护以((i,j))为左上角的正方形里最大最小分别是多少,存到数组里,然后遍历找答案,就这样

    下面放代码

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cctype>
    #include<queue>
    #define ll long long
    #define gc getchar
    #define maxn 1005
    using namespace std;
    
    inline ll read(){
        ll a=0;int f=0;char p=gc();
        while(!isdigit(p)){f|=p=='-';p=gc();}
        while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
        return f?-a:a;
    }int n,m,l,ans=2147483647,a[maxn][maxn];
    int a1[maxn][maxn],a2[maxn][maxn],b1[maxn][maxn],b2[maxn][maxn];
    
    struct ahaha{
        int s,id;
    }s1[maxn],s2[maxn];int h1=1,h2=1,t1,t2;
    
    int main(){
        n=read();m=read();l=read();
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                a[i][j]=read();
        for(int i=1;i<=n;++i){
            for(int j=1;j<l;++j){
                while(h1<=t1&&a[i][j]>=s1[t1].s)--t1;
                while(h2<=t2&&a[i][j]<=s2[t2].s)--t2;
                s1[++t1]=s2[++t2]={a[i][j],j};
            }
            for(int j=l;j<=m;++j){
                while(h1<=t1&&j-s1[h1].id>=l)++h1;
                while(h2<=t2&&j-s2[h2].id>=l)++h2;
                while(h1<=t1&&a[i][j]>=s1[t1].s)--t1;
                while(h2<=t2&&a[i][j]<=s2[t2].s)--t2;
                s1[++t1]=s2[++t2]={a[i][j],j};
                a1[i][j-l+1]=s1[h1].s,a2[i][j-l+1]=s2[h2].s;
            }
            h1=h2=1,t1=t2=0;
        }m-=l-1;
        for(int i=1;i<=m;++i){
            for(int j=1;j<l;++j){
                while(h1<=t1&&a1[j][i]>=s1[t1].s)--t1;
                while(h2<=t2&&a2[j][i]<=s2[t2].s)--t2;
                s1[++t1]={a1[j][i],j},s2[++t2]={a2[j][i],j};
            }
            for(int j=l;j<=n;++j){
                while(h1<=t1&&j-s1[h1].id>=l)++h1;
                while(h2<=t2&&j-s2[h2].id>=l)++h2;
                while(h1<=t1&&a1[j][i]>=s1[t1].s)--t1;
                while(h2<=t2&&a2[j][i]<=s2[t2].s)--t2;
                s1[++t1]={a1[j][i],j};s2[++t2]={a2[j][i],j};
                b1[j-l+1][i]=s1[h1].s,b2[j-l+1][i]=s2[h2].s;
            }
            h1=h2=1,t1=t2=0;
        }n-=l-1;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                ans=min(ans,b1[i][j]-b2[i][j]);
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    C#-项目属性设置
    SQL--连接字符串总结
    希尔排序实现(不太满意)
    选择排序实现
    用位运算实现 | 与 ^ 的功能
    如何初始化一个定长List<T>
    线程池与Threadlocal
    常用类
    基本数据类型介绍
    eclipse快捷键
  • 原文地址:https://www.cnblogs.com/hanruyun/p/10282616.html
Copyright © 2011-2022 走看看