intwork(int x){ int ans = 0; while (!s1.empty()) s1.pop();//清空两个栈 while (!s2.empty()) s2.pop(); s1.push(0);s2.push(0);//保证不访问空栈 for (int i = 1;i <= m + 1;++i) { int now = h[x][i];//当前位置最大的 F 连续高度 if (now > s1.top()) {s1.push(now),s2.push(1);}//直接进栈的情况 else { int wid = 0; while (!s1.empty() && now < s1.top()) { wid += s2.top();//累加高度 ans = max(ans,wid * s1.top();//更新答案 s1.pop(),s2.pop(); } s1.push(now),s2.push(wid+1);//最后入栈 } } return ans; }
对于每一行,我们都执行一个这样的过程
1 2
int ans = 0; for (int i = 1;i <= n;++i) ans = max(ans,work(i));
#include<cstring> #include<iostream> #include<cstdio> #include<cctype> #include<cmath> #include<stack> #include<algorithm> usingnamespace std; #define ll long long #define ri register int
char buf[1 << 20], *p1, *p2; //#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2)?EOF: *p1++) inlineintread(){ ri v = getchar();int f = 1,t = 0; while (!isdigit(v)) {if (v == '-')f = -1;v = getchar();} while (isdigit(v)) {t = t * 10 + v - 48;v = getchar();} return t *= f; }
constint N = 1e3+10;
int n,m,h[N][N];
char g[N][N];
stack <int> s1,s2;
intwork(int x){ int ans = 0; while (!s1.empty()) s1.pop(); while (!s2.empty()) s2.pop(); s1.push(0);s2.push(0); for (int i = 1;i <= m + 1;++i) { int now = h[x][i]; if (now > s1.top()) {s1.push(now),s2.push(1);} else { int wid = 0; while (!s1.empty() && now < s1.top()) { wid += s2.top(); ans = max(ans,wid * s1.top()); s1.pop(),s2.pop(); } s1.push(now),s2.push(wid+1); } } return ans; }
voidsolve(){ memset(h,0,sizeof h); cin >> n >> m; for (int i = 1;i <= n;++i) { for (int j = 1;j <= m;++j) { cin >> g[i][j]; if (g[i][j] == 'F') h[i][j] = h[i-1][j] + 1; } } int ans = 0; for (int i = 1;i <= n;++i) ans = max(ans,work(i)); printf("%d\n",ans * 3); }
signedmain(){ int T;cin >> T; while (T--) solve(); return0; }