思路
我在思考的时候能隐约的感觉到这应该是用单调栈做,但是始终无法得知做法的细节。理解之后,我来写下一些心得。
这道题的策略就是使用单调栈来排除无关答案。在读取每一行的时候,我们都可以计算出列的部分(因为我们是在读取每一行的时候计算,也就是说,我们在计算时读取并不是完成了的)能向上、向左和向右延伸的大小并且取最大值。
我把注释写在代码里了。看代码吧。
代码
// CH1803.cpp
// includings;
#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
using namespace std;
const int maxn = 1010;
// n,m stands for the boundaries;
// h stands for the height of streching up;
// l stands for the left bound;
// r stands for the right bound;
int n, m, h[maxn], l[maxn], r[maxn], ans;
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
char ch;
while (ch = getchar())
if (ch == 'F' || ch == 'R')
break;
// do statistics on the max height;
if (ch == 'F')
h[j]++;
else
h[j] = 0;
}
// rese;
memset(l, 0, sizeof(l));
memset(r, 0, sizeof(r));
stack<int> st;
for (int i = 1; i <= m; i++)
{
// delete the higher ones;
while (!st.empty() && h[i] <= h[st.top()])
st.pop();
// set the bound;
if (!st.empty())
l[i] = st.top();
else
l[i] = 0;
st.push(i);
}
// clear the stack;
while (!st.empty())
st.pop();
for (int i = m; i >= 1; i--)
{
// delete the higher ones;
while (!st.empty() && h[i] <= h[st.top()])
st.pop();
// set the right bound;
if (!st.empty())
r[i] = st.top();
else
r[i] = m + 1;
st.push(i);
}
// do statistics on this;
for (int i = 1; i <= m; i++)
ans = max(ans, (h[i] * ((r[i] - 1) - (l[i] + 1) + 1)));
}
// output it;
printf("%d\n", 3 * ans);
return 0;
}
// CH1803.cpp
// includings;
#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
using namespace std;
const int maxn = 1010;
// n,m stands for the boundaries;
// h stands for the height of streching up;
// l stands for the left bound;
// r stands for the right bound;
int n, m, h[maxn], l[maxn], r[maxn], ans;
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
char ch;
while (ch = getchar())
if (ch == 'F' || ch == 'R')
break;
// do statistics on the max height;
if (ch == 'F')
h[j]++;
else
h[j] = 0;
}
// rese;
memset(l, 0, sizeof(l));
memset(r, 0, sizeof(r));
stack<int> st;
for (int i = 1; i <= m; i++)
{
// delete the higher ones;
while (!st.empty() && h[i] <= h[st.top()])
st.pop();
// set the bound;
if (!st.empty())
l[i] = st.top();
else
l[i] = 0;
st.push(i);
}
// clear the stack;
while (!st.empty())
st.pop();
for (int i = m; i >= 1; i--)
{
// delete the higher ones;
while (!st.empty() && h[i] <= h[st.top()])
st.pop();
// set the right bound;
if (!st.empty())
r[i] = st.top();
else
r[i] = m + 1;
st.push(i);
}
// do statistics on this;
for (int i = 1; i <= m; i++)
ans = max(ans, (h[i] * ((r[i] - 1) - (l[i] + 1) + 1)));
}
// output it;
printf("%d\n", 3 * ans);
return 0;
}
// CH1803.cpp // includings; #include <iostream> #include <cstdio> #include <stack> #include <cstring> using namespace std; const int maxn = 1010; // n,m stands for the boundaries; // h stands for the height of streching up; // l stands for the left bound; // r stands for the right bound; int n, m, h[maxn], l[maxn], r[maxn], ans; int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { char ch; while (ch = getchar()) if (ch == 'F' || ch == 'R') break; // do statistics on the max height; if (ch == 'F') h[j]++; else h[j] = 0; } // rese; memset(l, 0, sizeof(l)); memset(r, 0, sizeof(r)); stack<int> st; for (int i = 1; i <= m; i++) { // delete the higher ones; while (!st.empty() && h[i] <= h[st.top()]) st.pop(); // set the bound; if (!st.empty()) l[i] = st.top(); else l[i] = 0; st.push(i); } // clear the stack; while (!st.empty()) st.pop(); for (int i = m; i >= 1; i--) { // delete the higher ones; while (!st.empty() && h[i] <= h[st.top()]) st.pop(); // set the right bound; if (!st.empty()) r[i] = st.top(); else r[i] = m + 1; st.push(i); } // do statistics on this; for (int i = 1; i <= m; i++) ans = max(ans, (h[i] * ((r[i] - 1) - (l[i] + 1) + 1))); } // output it; printf("%d\n", 3 * ans); return 0; }