其實就是BZOJ3039 不過沒權限號(粗鄙之語)html
同時也是洛谷4147ios
就是求最大子矩陣而後*3spa
懸線法.net
有個博客講的不錯https://blog.csdn.net/u012288458/article/details/48197727code
GREED-VI大佬以前也講過,友鏈一下https://www.cnblogs.com/GREED-VI/p/9887399.html (他說的實際上是懸線法,掃描線和這個不同的吧)htm
水水水blog
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define N 1005 using namespace std; int n,m; int ans; int up[N][N],L[N][N],R[N][N]; pair<int,int> st[N]; bool v[N][N],f_fall; void init() { char ch; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>ch; v[i][j]=(ch=='F'?1:0); if(v[i][j]) f_fall=1; } } void solve() { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(!v[i][j]) up[i][j]=0; else up[i][j]=up[i-1][j]+1; for (int i=1;i<=n;i++) { int top=0; st[++top]=make_pair(-1,0); for (int j=1;j<=m;j++) { while (up[i][j]<=st[top].first) top--; L[i][j]=j-st[top].second-1; st[++top]=make_pair(up[i][j],j); } } for (int i=1;i<=n;i++) { int top=0; st[++top]=make_pair(-1,m+1); for (int j=m;j>=1;j--) { while (up[i][j]<=st[top].first) top--; R[i][j]=st[top].second-j-1; st[++top]=make_pair(up[i][j],j); } } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans=max(ans,(L[i][j]+R[i][j]+1)*up[i][j]); ans*=3; } int main() { //freopen("cpp.in","r",stdin); //freopen("cpp.out","w",stdout); int Q;scanf("%d",&Q); while(Q--) { f_fall=0; init(); if(f_fall==0) printf("0\n"); else{ solve(); printf("%d\n",ans); ans=0; memset(v,0,sizeof(v)); memset(up,0,sizeof(up)); memset(L,0,sizeof(L)); memset(R,0,sizeof(R)); memset(st,0,sizeof(st)); } } return 0; }