• 【Luogu】P1169棋盘制作(单调栈)


      题目链接

      唉……这种题放在NOIP以前我是会做的……但是为什么现在反而不会了……

      单调栈。预处理每个点向上能扩展的最大距离,左右用两遍单调栈扫一遍。注意边界。

      

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<cctype>
    using namespace std;
    
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    int q[2010][2010];
    int d[2010][2010][2];
    int w[2020];int s[2020];
    int stack[2020],top;
    int ans;
    int cnt;
    
    int main(){
        int n=read(),m=read();
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j){
                q[i][j]=read()^((i+j+1)%2);
                int now=q[i][j];
                d[i][j][now]=q[i-1][j]==now?d[i-1][j][now]+1:1;
            }
        for(int i=1;i<=n;++i){
            memset(w,0,sizeof(w));    top=0;
            for(int j=1;j<=m;++j){
                w[j]=j;
                while(top&&d[i][stack[top]][0]>d[i][j][0])    w[stack[top--]]=j-1;
                stack[++top]=j;
            }
            //while(top)    w[stack[top--]]=n;
            memset(s,0,sizeof(s));    top=0;
            for(int j=m;j>=1;--j){
                s[j]=j;
                while(top&&d[i][stack[top]][0]>d[i][j][0])    s[stack[top--]]=j+1;
                stack[++top]=j;
            }
            //while(top)    s[stack[top--]]=1;
            for(int j=1;j<=m;++j){
                ans=max(ans,(w[j]-s[j]+1)*d[i][j][0]);
                int MIN=min(w[j]-s[j]+1,d[i][j][0]);
                cnt=max(cnt,MIN*MIN);
            }
        }
        for(int i=1;i<=n;++i){
            memset(w,0,sizeof(w));    top=0;
            for(int j=1;j<=m;++j){
                w[j]=j;
                while(top&&d[i][stack[top]][1]>d[i][j][1])    w[stack[top--]]=j-1;
                stack[++top]=j;
            }
            //while(top)    w[stack[top--]]=n;
            memset(s,0,sizeof(s));    top=0;
            for(int j=m;j>=1;--j){
                s[j]=j;
                while(top&&d[i][stack[top]][0]>d[i][j][1])    s[stack[top--]]=j+1;
                stack[++top]=j;
            }
            //while(top)    s[stack[top--]]=1;
            for(int j=1;j<=m;++j){
                ans=max(ans,(w[j]-s[j]+1)*d[i][j][1]);
                int MIN=min(w[j]-s[j]+1,d[i][j][1]);
                cnt=max(cnt,MIN*MIN);
            }
        }
        printf("%d
    %d",cnt,ans);
        return 0;
    }
  • 相关阅读:
    【PAT甲级】1054 The Dominant Color
    【PAT甲级】1001 A+B Format
    【算法】二分排序和二分查找
    【PAT甲级】1008 Elevator (20分)
    移动端工作准备
    媒体查询
    多列布局
    怪异盒模型
    弹性盒
    圆角
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8315186.html
Copyright © 2020-2023  润新知