zoukankan      html  css  js  c++  java
  • bzojj1764: [Baltic2009]monument

    Description

    给一个p*q*r的立方体,它由p*q*r个1*1*1的小立方体构成。每个立方体要么被虫蛀,要么不被。现在郑爽要选出一个a*a*b的立方体(方向任意),使得它没有被虫蛀过,并且4*a*b最大。

    Input

    第一行是p,q,r <= 150。 以下p*q行,每行r个字符。(x,y,z)这个格子,出现在输入的第1 + (y * p + x - p)行的第z个字符。 N代表未被虫蛀,P代表被虫蛀了。

    Output

    仅一行,代表郑爽需要的最大的4ab
    将悬线扫描法推广至三维,同一层内记录以每个格子为左上角的最大全N正方形的边长a,另外记录以这个正方形边长,向前/后能延伸到的位置(相差b)。
    由于方向任意,翻转坐标系计算三次可得到答案。
    #include<cstdio>
    #include<algorithm>
    int p,q,r,ans=0;
    bool d[157][157][157];
    char s[157][157][157];
    int f[157][157][157],f1[157][157][157],f2[157][157][157],stk[157],stp=0;
    int min(int a,int b){return a<b?a:b;}
    void maxs(int&a,int b){if(a<b)a=b;}
    void calc(){
        for(int i=1;i<=p;++i){
            for(int j=1;j<=q;++j){
                for(int k=1;k<=r;++k){
                    f[i][j][k]=(s[i][j][k]?1+min(f[i][j-1][k],min(f[i][j-1][k-1],f[i][j][k-1])):0);
                }
            }
        }
        for(int j=1;j<=q;++j){
            for(int k=1;k<=r;++k){
                for(int i=1;i<=p;++i){
                    while(stp&&f[stk[stp]][j][k]>f[i][j][k])f1[stk[stp--]][j][k]=i-1;
                    stk[++stp]=i;
                }
                while(stp)f1[stk[stp--]][j][k]=p;
                for(int i=p;i;--i){
                    while(stp&&f[stk[stp]][j][k]>f[i][j][k])f2[stk[stp--]][j][k]=i;
                    stk[++stp]=i;
                }
                while(stp)f2[stk[stp--]][j][k]=0;
            }
        }
        for(int i=1;i<=p;++i){
            for(int j=1;j<=q;++j){
                for(int k=1;k<=r;++k){
                    maxs(ans,f[i][j][k]*(f1[i][j][k]-f2[i][j][k]));
                }
            }
        }
    }
    int main(){
        scanf("%d%d%d",&q,&p,&r);
        for(int i=1;i<=p;++i){
            for(int j=1;j<=q;++j){
                scanf("%s",s[i][j]+1);
                for(int k=1;k<=r;++k)s[i][j][k]=(s[i][j][k]=='N'?1:0);
            }
        }
        calc();
        for(int i=1;i<=p;++i){
            for(int j=1;j<=q;++j){
                for(int k=1;k<=r;++k)if(!d[i][j][k]){
                    d[i][j][k]=d[j][i][k]=1;
                    std::swap(s[i][j][k],s[j][i][k]);
                }
            }
        }
        std::swap(p,q);
        calc();
        for(int i=1;i<=p;++i){
            for(int j=1;j<=q;++j){
                for(int k=1;k<=r;++k)if(d[i][j][k]){
                    d[i][j][k]=d[k][j][i]=0;
                    std::swap(s[i][j][k],s[k][j][i]);
                }
            }
        }
        std::swap(p,r);
        calc();
        printf("%d
    ",ans*4);
        return 0;
    }
  • 相关阅读:
    URAL-1998 The old Padawan 二分
    URAL-1997 Those are not the droids you're looking for 二分匹配
    URAL-1991 The battle near the swamp 水题
    URAL-1989 Subpalindromes 多项式Hash+树状数组
    URAL-1987 Nested Segments 线段树简单区间覆盖
    URAL-1981 Parallel and Perpendicular 水题
    k8s-api
    golang test模块
    k8s-calico
    docker设置proxy
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6052982.html
Copyright © 2011-2022 走看看