!-- Loading 底层遮罩 -->

P4147 玉蟾宫

传送门

思路

悬线法:一种求解给定矩阵中的极大矩阵的算法。通过三个数组来逐行计算可能的矩形面积以求解出最大子矩形。该方法适用于地图小,障碍点多的问题。

典型的悬线法求解最大矩形。定义左移,右移,悬线三个数组,初始化和预处理左移和右移数组,遍历整个矩阵的过程中更新三个数组的值,同时求解每个位置的最大矩形面积并更新答案。 

 代码

#include<iostream>
#define MAXN 1010
using namespace std;
char mari[MAXN][MAXN];
int hi[MAXN][MAXN], le[MAXN][MAXN], ri[MAXN][MAXN], ans;
int main(void)
{
    int N = 0, C = 0;
    cin>>N>>C;
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j <= C; j++)
        {
            cin >> mari[i][j];
            hi[i][j] = 1;
            ri[i][j] = le[i][j] = j;
        }
        for (int j = 2; j <= C; j++)
        {
            if (mari[i][j]=='F'&& mari[i][j - 1] == 'F')
                le[i][j] = le[i][j - 1];
        }
        for (int j = C - 1; j >= 1; j--)
        {
            if (mari[i][j]=='F'&& mari[i][j + 1] == 'F')
                ri[i][j] = ri[i][j + 1];
        }
    }
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j <= C; j++)
        {
            if (mari[i][j] == 'F')
            {
                if (i>1&&mari[i - 1][j] == 'F')
                {
                    hi[i][j] = hi[i - 1][j] + 1;
                    if (le[i - 1][j] > le[i][j])
                        le[i][j] = le[i - 1][j];
                    if (ri[i - 1][j] < ri[i][j])
                        ri[i][j] = ri[i - 1][j];
                }
                if ((ri[i][j] - le[i][j] + 1) * hi[i][j] > ans)
                    ans = (ri[i][j] - le[i][j] + 1) * hi[i][j];
            }
        }
    }
    cout << 3 * ans;
    return 0;
}

 

posted @ 2022-03-30 21:06  Thinker-X  阅读(61)  评论(0)    收藏  举报