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\n",ans*4);
    return 0;
}
时间: 2024-11-13 12:10:41

bzojj1764: [Baltic2009]monument的相关文章

[bzoj 1355][Baltic2009]Radio Transmission

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1355 [Baltic2009]Radio Transmission Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 912  Solved: 626[Submit][Status][Discuss] Description 给你一个字符串,它是由某个字符串不断自我连接形成的. 但是这个字符串是不确定的,现在只想知道它的最短长度是多少. Inpu

bzoj1355【Baltic2009】Radio Transmission

1355: [Baltic2009]Radio Transmission Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 649  Solved: 426 [Submit][Status][Discuss] Description 给你一个字符串,它是由某个字符串不断自我连接形成的. 但是这个字符串是不确定的,现在只想知道它的最短长度是多少. Input 第一行给出字符串的长度,1 < L ≤ 1,000,000. 第二行给出一个字符串,全由小写字

bzoj 1761: [Baltic2009]beetle 区间dp

1761: [Baltic2009]beetle Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 255  Solved: 92[Submit][Status][Discuss] Description 在一条直线上有N个点,每个点M升水. 一个虫子在坐标轴0点上,它每个单位时间移动一格,每个点的水每单位时间消失1升. 问虫子最多可以喝到多少水,喝水的时间忽略不计 Input 第一行给出数字N,M 下面N行给出N个点的坐标Xi 0 ≤ n ≤ 300,

BZOJ 1355: [Baltic2009]Radio Transmission( kmp )

自己YY一下可以发现answer =  n - fail[ n ] ----------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i , n ) for( int i = 0 ; i

BZOJ-1355: [Baltic2009]Radio Transmission (傻逼KMP)

1355: [Baltic2009]Radio Transmission Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1046  Solved: 722[Submit][Status][Discuss] Description 给你一个字符串,它是由某个字符串不断自我连接形成的. 但是这个字符串是不确定的,现在只想知道它的最短长度是多少. Input 第一行给出字符串的长度,1 < L ≤ 1,000,000. 第二行给出一个字符串,全由小写字母

[ABC 099] B-Stone Monument

B - Stone Monument Time limit : 2sec / Memory limit : 256MB Score : 200 points Problem Statement In some village, there are 999 towers that are 1,(1+2),(1+2+3),-,(1+2+3+-+999) meters high from west to east, at intervals of 1 meter. It had been snowin

bzoj1760 [Baltic2009]Triangulation

给定一个多边形的三角剖分(n<=1e5),且每个三角形有其颜色,问最多可以把这个三角剖分分成几个联通的部分,使任何一种颜色不出现在多个连通块中 建出三角剖分对应的树,同种颜色的点之间的路径是不能被切开的,因此将同色的点间路径标记一下,未标记的边数即为答案 具体实现可以用树上差分进行标记,树链剖分lca,同色的点按dfs序排序并将排序后相邻的点间路径标记 #include<cstdio> #include<algorithm> typedef long long i64; co

1355: [Baltic2009]Radio Transmission

Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 958  Solved: 659[Submit][Status][Discuss] Description 给你一个字符串,它是由某个字符串不断自我连接形成的. 但是这个字符串是不确定的,现在只想知道它的最短长度是多少. Input 第一行给出字符串的长度,1 < L ≤ 1,000,000. 第二行给出一个字符串,全由小写字母组成. Output 输出最短的长度 Sample Input 8 cabc

bzoj1355 [Baltic2009]Radio Transmission

Description 给你一个字符串,它是由某个字符串不断自我连接形成的. 但是这个字符串是不确定的,现在只想知道它的最短长度是多少. Input 第一行给出字符串的长度,1 < L ≤ 1,000,000. 第二行给出一个字符串,全由小写字母组成. Output 输出最短的长度 Sample Input 8 cabcabca Sample Output 3 HINT 对于样例,我们可以利用"abc"不断自我连接得到"abcabcabc",读入的cabcab