思路:悬线法求解最大子矩阵
分析:
1 详细资料请见点击打开链接
2 有个地方需要注意的是输入格式,有可能输入字母后面会有多个空格,所以必须要过滤掉这些空格
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int MAXN = 1010; int mat[MAXN][MAXN]; int up[MAXN][MAXN] , Left[MAXN][MAXN] , Right[MAXN][MAXN]; int n , m; int solve(){ int ans = 0; int leftNum , rightNum; for(int i = 1 ; i <= n ; i++){ //从左往右求最大的左边列编号 leftNum = 0; for(int j = 1 ; j <= m ; j++){ if(!mat[i][j]){ up[i][j] = 0; Left[i][j] = 0; leftNum = j; } else{ up[i][j] = i == 1 ? 1 : up[i-1][j]+1; Left[i][j] = i == 1 ? leftNum+1 : max(Left[i-1][j] , leftNum+1); } } //从右往左求最小的右边列编号 rightNum = m+1; for(int j = m ; j >= 1 ; j--){ if(!mat[i][j]){ Right[i][j] = m+1; rightNum = j; } else{ Right[i][j] = i == 1 ? rightNum-1 : min(Right[i-1][j] , rightNum-1); ans = max(ans , up[i][j]*(Right[i][j]-Left[i][j]+1)); } } } return 3*ans; } int main(){ int Case; char c; scanf("%d" , &Case); while(Case--){ scanf("%d%d" , &n , &m); for(int i = 1 ; i <= n ; i++){ for(int j = 1 ; j <= m ; j++){ c = getchar(); while(c != 'F' && c != 'R') c = getchar(); mat[i][j] = c == 'F' ? 1 : 0; } } printf("%d\n" , solve()); } return 0; }
时间: 2024-10-29 04:41:13