題意:
一個由'R'和'F'組成的m*n的矩陣,求全部F的子矩陣最大,輸出結果*3.
分析:
比較容易想到的是枚舉每個矩陣的左上和右下的頂點然後統計,這樣的時間複雜度O(N^4)太慢了,其實可以把從i行到矩陣第一行看成一個一維數組,其中裏面的數字表示的就是這一列的高度,記up[i],表示第i列在第i行的高度,up的維護比較簡單,如果當前元素是'R'則up[i] = 0, 否則up[i] += 1,那麼答案就是枚舉每列,統計其向右向左的最大延伸距離,使用l, r, 數組標記,具體看Code.
Code:
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define DIR 4
#define DIM 2
#define STATUS 2
#define MAXN 1000 + 10
#define MAXM 100000 + 10
#define oo (~0u)>>1
#define INF 0x3F3F3F3F
#define REPI(i, s, e) for(int i = s; i <= e; i ++)
#define REPD(i, e, s) for(int i = e; i >= s; i --)
static const double EPS = 1e-5;
typedef struct ArcNode_ {
int u, v, w, next;
}ArcNode;
int l[MAXN];
int r[MAXN];
int up[MAXN];
char g[MAXN][MAXN];
int scan(int n)
{
REPI(i, 1, n) {
l[i] = r[i] = i;
}
REPI(i, 2, n) { //cal l.
while( l[i] > 1 && up[i] <= up[l[i]-1] ) {
l[i] = l[l[i]-1];
}
}
REPD(i, n-1, 1) { //cal r.
while( r[i] < n && up[i] <= up[r[i]+1] ) {
r[i] = r[r[i]+1];
}
}
int sum = 0;
REPI(i, 1, n) {
sum = max(sum, (r[i]-l[i]+1)*up[i]);
}
return sum;
}
int cal(int n, int m)
{
int ans = 0;
memset(up, 0, sizeof(up));
REPI(i, 1, n) {
REPI(j, 1, m) {
up[j] = ( 'F' == g[i][j] )? up[j]+1 : 0;
}
ans = max(ans, scan(m));
}
return ans;
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int cas;
int n;
int m;
char ch[2];
scanf("%d", &cas);
REPI(k, 1, cas) {
scanf("%d %d", &n, &m);
REPI(i, 1, n) {
getchar();
REPI(j, 1, m) {
scanf("%s", ch);
g[i][j] = *ch;
}
}
printf("%d\n", cal(n,m)*3);
}
return 0;
}