题意:
给定一个n*m的矩阵,一些格子是空地“F”,一些是障碍"R",找出一个全部由F组成的面积最大的子矩阵;
思路:
对每个格子维护up[i][j],le[i][j],ri[i][j].表示这个格子能向上的最长的长度,这个长度能向左向右移动的最长距离:
面积的最大值就是ans=max(ans ,up[i][j]*(ri[i][j]-le[i][j]+1));
AC代码:
#include <bits/stdc++.h> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++) #define mst(ss,b) memset(ss,b,sizeof(ss)); typedef long long LL; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<‘0‘||CH>‘9‘;F= CH==‘-‘,CH=getchar()); for(num=0;CH>=‘0‘&&CH<=‘9‘;num=num*10+CH-‘0‘,CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + ‘0‘); putchar(‘\n‘); } const LL mod=1e9+7; const double PI=acos(-1.0); const LL inf=1e18; const int N=2e5+10; const int maxn=1005; const double eps=1e-10; char mp[maxn][maxn],s[2*maxn]; int up[maxn][maxn],le[maxn][maxn],ri[maxn][maxn],n,m; int main() { int t; read(t); while(t--) { read(n);read(m); mst(up,0); mst(le,0); mst(ri,0); For(i,1,n) { For(j,1,m) { scanf("%s",s); mp[i][j]=s[0]; } } For(i,1,n) { For(j,1,m) { if(mp[i][j]==‘F‘)up[i][j]= i==1?1:up[i-1][j]+1; else up[i][j]=0; } } int ans =0; For(i,1,n) { int lo=0,ro=m+1; For(j,1,m) { if(mp[i][j]==‘F‘)le[i][j]= i==1?lo+1:max(lo+1,le[i-1][j]); else le[i][j]=j+1,lo=j; } for(int j=m;j>0;j--) { if(mp[i][j]==‘F‘)ri[i][j]= i==1?ro-1:min(ro-1,ri[i-1][j]); else ri[i][j]=j-1,ro=j; } For(j,1,m) { if(mp[i][j]==‘F‘)ans=max(ans,(ri[i][j]-le[i][j]+1)*up[i][j]); } } cout<<3*ans<<"\n"; } return 0; }
时间: 2024-11-16 14:06:24