思路:对每一个格子进行处理:计算包含它的最大矩形。
up[i][j]: 存储矩形的高;
left[i][j]: 存储矩形的左边界的列号;
right[i][j]:存储矩形的右边界的列号。
面积 = up[i][j] * ( right[i][j] - left[i][j] +1 )。
心得:即便是有了思路,写代码前也要在纸上画画,模拟模拟。否则就像代码中提示注意的地方,写成了0,估计debug半天也不知道错在哪了。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <string> #include <stack> #include <queue> #include <set> #include <map> typedef long long ll; using namespace std; const int inf=0x3f3f3f3f; const int maxn=1e3+10; int mat[maxn][maxn],up[maxn][maxn]; int myleft[maxn][maxn],myright[maxn][maxn]; int m,n; int main() { int t; scanf("%d",&t); while(t--){ scanf("%d %d",&m,&n); char ch; for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ ch=getchar(); while(ch!=‘R‘ && ch!=‘F‘)ch=getchar(); if(ch==‘R‘)mat[i][j]=1; else mat[i][j]=0; } } /* for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ printf("%d ",mat[i][j] ); } printf("\n"); }*/ int ans=0,i,j; for(i=0;i<m;i++){//从上到下扫描 int lo=-1,ro=n;//lo表示左边障碍物的列号,ro同理。 for(j=0;j<n;j++){//从左到右扫描,处理up[][]和left[][]。 if(mat[i][j]==1){ lo=j; up[i][j]=0; myleft [i][j]=0; }else{ up[i][j]=(i==0?1:up[i-1][j]+1); myleft[i][j]=(i==0?lo+1:max(myleft[i-1][j],lo+1));// !!! } } for(int j=n-1;j>=0;j--){//从右往左扫描,处理right[][]。 if(mat[i][j]==1){ ro=j; myright[i][j]=n;//注意细节 }else{ myright[i][j]=(i==0?ro-1:min(myright[i-1][j],ro-1));// !!! ans=max(ans,up[i][j]*(myright[i][j]-myleft[i][j]+1)); } } } printf("%d\n",ans*3 ); } return 0; }
时间: 2024-10-11 00:26:25