简单的扫描算法
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1005; int T,M,N,mat[maxn][maxn],right[maxn][maxn],left[maxn][maxn],up[maxn][maxn]; int main() { scanf("%d",&T); while(T--) { int ans = 0; scanf("%d%d",&N,&M); char ch; for(int i = 1;i <= N;i++) { for(int j = 1;j <= M;j++) { scanf(" %c",&ch); mat[i][j] = (ch == 'R' ? 0 : 1); } } memset(right,0,sizeof(right)); memset(left,0,sizeof(left)); memset(up,0,sizeof(up)); for(int i = 1;i <= M;i++) { left[0][i] = right[0][i] = maxn; } for(int i = 1;i <= N;i++) { int lo = 0,ro = M + 1; for(int j = 1;j <= M;j++) { if(mat[i][j]) { if(mat[i - 1][j] == 0) { up[i][j] = 0; } else { up[i][j] = up[i - 1][j] + 1; } if(mat[i][j - 1] == 0) { left[i][j] = 0; } else if(mat[i - 1][j] == 0) { left[i][j] = j - lo - 1; } else { left[i][j] = min(left[i - 1][j],j - lo - 1); } } else { lo = j; } } for(int j = M;j >= 1;j--) { if(mat[i][j]) { if(mat[i][j + 1] == 0) { right[i][j] = 0; } else if(mat[i - 1][j] == 0) { right[i][j] = ro - j - 1; } else { right[i][j] = min(right[i - 1][j],ro - j - 1); } ans = max(ans,(up[i][j] + 1) * (left[i][j] + right[i][j] + 1) * 3); //printf("ans = %d,%d,%d,%d,%d,%d ",ans,i,j,left[i][j],right[i][j],up[i][j]); } else { ro = j; } } } printf("%d ",ans); } return 0; }