题意:多组数据(国外题好像都这样),每次n*m矩形,F表示空地,R表示障碍
求最大子矩阵(悬线法模板)
把每个格子向上延伸的空格看做一条悬线
以le[i][j],re[i][j],up[i][j]分别记录该悬线向左,向右的运动极限以及向上的延伸长度
ans=max(ans,(up[i][j]*(re[i][j]-le[i][j]+1)));
#include<cstdio> #include<iostream> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define int long long #define olinr return #define _ 0 #define love_nmr 0 #define DB double inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-f; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline void put(int x) { if(x<0) { x=-x; putchar('-'); } if(x>9) put(x/10); putchar(x%10+'0'); } int n; int m; bool mp[1050][1050]; int le[1050][1050]; int re[1050][1050]; int up[1050][1050]; int T; inline void init() { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { char ch=getchar(); while(!isupper(ch)) ch=getchar(); if(ch=='F') mp[i][j]=true; else mp[i][j]=false; } } inline int work() { int ans=0; for(int i=1;i<=n;i++) { int l=0; //当前障碍的位置 int r=m+1; for(int j=1;j<=m;j++) { if(!mp[i][j]) //有障碍 { up[i][j]=le[i][j]=0; l=j; } else { up[i][j]=i==1? 1:up[i-1][j]+1; //更新 le[i][j]=i==1? l+1:max(le[i-1][j],l+1); } } for(int j=m;j>=1;j--) { if(!mp[i][j]) { re[i][j]=m+1; r=j; } else { re[i][j]=i==1? r-1:min(r-1,re[i-1][j]); //更新re ans=max(ans,up[i][j]*(re[i][j]-le[i][j]+1)); //更新答案 } } } return ans*3; //要求面积*3 } signed main() { T=read(); while(T--) { n=read(); m=read(); init(); put(work()); putchar(' '); } olinr ~~(0^_^0)+love_nmr; } /* 2 5 6 RFFFFF FFFFFF RRRFFF FFFFFF FFFFFF 5 5 RRRRR RRRRR RRRRR RRRRR RRRRR */