【UVALive】3029 City Game(悬线法)

题目

传送门:QWQ

分析

以前见到过差不多的这题。

xhk说是单调栈水题,但我又不会单调栈,于是当时就放下了。

这么久过去了我还是不会用单调栈做这题,用的是悬线法。

非常好写

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1005;
int up[maxn][maxn], left[maxn][maxn], right[maxn][maxn], A[maxn][maxn];
int main(){
    int T; scanf("%d",&T);
    while(T--){
        memset(up,0,sizeof(up));memset(left,0,sizeof(left));memset(right,0,sizeof(right));memset(A,0,sizeof(A));
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            char s[5]; scanf("%s",s);
            if(s[0]=='F') A[i][j]=1;
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            int lo=0, ro=m+1;
            left[i][1]=1; right[i][m]=m;
            for(int j=1;j<=m;j++)
                if(!A[i][j]){up[i][j]=left[i][j]=0;lo=j;}
                else{
                    up[i][j]=up[i-1][j]+1; if(i==1) left[i][j]=lo+1; else left[i][j]=max(left[i-1][j],lo+1);
                }
            for(int j=m;j>=1;j--)
                if(!A[i][j]) ro=j,right[i][j]=m;
                else{
                    if(i==1) right[i][j]=ro-1; else right[i][j]=min(right[i-1][j],ro-1);
                    ans=max(ans,up[i][j]*(right[i][j]-left[i][j]+1));
                //    if(ans==up[i][j]*(right[i][j]-left[i][j]+1)) printf("-----  %d %d %d %d %d
",i,j,up[i][j],left[i][j],right[i][j]);
                }
        }
        printf("%d
",ans*3);
    }
    return 0;
}
/*
2
5 6
R F F F F F
F F F F F F
R R R F F F
F F F F F F
F F F F F F
5 5
R R R R R
R R R R R
R R R R R
R R R R R
R R R R R
2
5 6
R F F F F F
F F F F R F
R R R F F F
F F F F R F
F F F F F F
5 5
R R R R R
R F R R R
R R R F R
R R R R R
R F R R R
*/
原文地址:https://www.cnblogs.com/noblex/p/9223548.html