给你N×M大的矩阵,里面分别有字符‘F'和’R',要找到一个最大的只有‘F'的矩阵,不能包含有’R‘。N,M<=1000。
一开始的思路是单调栈来求最大矩形面积,因为没看清题目不能包含’R'字符,所以算出每行的‘F'字符个数然后单调栈就WA了。。
然后想到要从左边开始,算出连续的‘F'字符个数,然后又WA了。
因为还有右边,所以右边开始的’F'字符也处理一下,也是WA。
接着想到这种情形:
R F F F R
R F F F R
这枚举F的开始结束的话都是不行的,那么因为就两种字符。然后我又上一步一样只是求出R连续的大小,然后统计
lf左边开始‘F'的连续个数然后单调栈
rf右边开始’F'的连续个数然后单调栈
lr左边开始‘R'的连续个数然后单调栈
rr右边开始’R'的连续个数然后单调栈。
那么答案我就觉得是max(lf,rf,n*m-max(lr,rr))
然后也WA,因为我想到一个反例:
R R R R R
R F F F R
R F F F R
R F F F R
R R R R R
仔细观察这个样例,发现其实之前的做法很麻烦,我们最后得出的矩形一定是有左边的(废话),但是这个左边不确定,只要确定了直接用单调栈就出来了。
所以想到可以枚举K列,每次从第K列开始算。代码如下:
#include <iostream> #include <fstream> #include <stdio.h> #include <string> #include <string.h> #include <algorithm> using namespace std; int n,m,arr[2333],stk[2333],w[2333]; char ma[2333][2333],ss[233]; long long ans; int main() { int k; scanf("%d",&k); while(k--) { long long lr,rr,lf,rf; lr=rr=lf=rf=0; memset(stk,0,sizeof stk); ans=0; memset(w,0,sizeof w); scanf("%d%d",&n,&m); for(int i=1; i<=n; ++i) { for(int j=1; j<=m; ++j) scanf("%s",ss),ma[i][j]=ss[0]; } for(int k=1; k<=m; ++k) { for(int i=1; i<=n; ++i) { int tmp=0; int j=k; while(j<=m&&ma[i][j++]!='R') ++tmp; /* for(int j=1;j<=m;++j) if(ma[i][j]=='F') ++tmp; */ arr[i]=tmp; } memset(stk,0,sizeof stk); memset(w,0,sizeof w); lf=0; arr[n+1]=0; int p=0; for(int i=1; i<=n+1; ++i) { if(arr[i]>stk[p]) stk[++p]=arr[i],w[p]=1; else { int wid=0; while(stk[p]>arr[i]) { wid+=w[p]; lf=max(lf,(long long)wid*stk[p]); --p; } stk[++p]=arr[i]; w[p]=wid+1; } } ans=max(ans,lf); } printf("%lld ",ans*3); } return 0; }