洛谷P1169_悬线法求最大矩阵面积

求最大的x矩阵的面积

h[maxn][maxn]记录该位置向上最多扩展的位置

初始化:第0行全置位0

更新: h[i][j] = a[i][j]==x?h[i - 1][j]+1:0;

l[maxn][maxn], r[maxn][maxn];记录向左/右最先到达不是x的位置

tmp记录上一次不为x的位置的列号

初始化:将l[][]的第0行全置位0,r[][]的第0行全置位m+1

更新:如果当前位置是x, 则l[i][j] = max(l[i - 1][j], tmp), r[i][j] = min(r[i - 1][j], tmp)

           反之,将tmp置位该位置的列号,该位置的值置为l[i][j] = 0,r[i][j] = m + 1(为了不对下面的行产生影响)

*********************************************************************************************************************

面积计算,该位置:

若是最大矩阵:(r[i][j]-l[i][j]-1) * h[i][j]

若是最大正方形:min(r[i][j]-l[i][j]-1, h[i][j]) * min(r[i][j]-l[i][j]-1, h[i][j])

*********************************************************************************************************************

#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 2010;

int a[maxn][maxn];
int h[maxn][maxn], l[maxn][maxn], r[maxn][maxn];

int n, m;
int ans1, ans2;

void solve(bool x);//求最大的x矩阵

int main()
{
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
    {
        scanf("%d", &a[i][j]);
        if((i&1)!=(j&1)) a[i][j] = !a[i][j];//按此方法将问题转化
    }
    ans1 = ans2 = 0;
    solve(1);
    solve(0);
    printf("%d\n%d\n", ans1, ans2);
    return 0;
}

void solve(bool x)
{
    //初始化
    int i, j;
    for(i = 0; i <= m; ++i)
    {
        h[0][i] = 0;
        l[0][i] = 0;
        r[0][i] = m + 1;
    }

    for(i = 1; i <= n; ++i)
    {
        for(j = 1; j <= m; ++j) h[i][j] = a[i][j]==x?h[i - 1][j]+1:0;
        int tmp = 0;//初始认为向左初次达到不是x的位置是0;
        for(j = 1; j <= m; ++j)
            if(a[i][j]==x) l[i][j] = max(l[i - 1][j], tmp);
            else l[i][j] = 0, tmp = j;//将不满足情况的l[i][j]=0,使其不对下一行产生影响
        tmp = m + 1;//初始认为向右初次达到不是x的位置是m+1;
        for(j = m; j; --j)
            if(a[i][j]==x) r[i][j] = min(r[i - 1][j], tmp);
            else r[i][j] = m + 1, tmp = j;
        for(j = 1; j <= m; ++j)
        {
            int tmp = r[i][j]-l[i][j]-1;
            ans2 = max(ans2, tmp*h[i][j]);
            int minn = min(tmp, h[i][j]);
            ans1 = max(ans1, minn*minn);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/jay__bryant/article/details/80160976