悬线法

悬线法

 

•用途

针对求给定矩阵中满足某条件的极大矩阵,比如“面积最大的长方形、正方形”“周长最长的矩形等等”。

•思路

悬线法是一条竖线,这条竖线要满足上端点在整个矩形上边界或者是一个障碍点。
然后以这条悬线进行左右移动,直到移至障碍点或者是矩阵边界,进而确定这条悬线所在的极大矩阵。
也就是说,我们要针对矩阵中每个点进行求极大矩阵的操作,
所以我们需要Left[]数组存每个点能到达的最右位置,Right[]数组存放每个点能到达的最左位置,Up[]数组位置。
设置好这些数组之后,我们开始遍历矩阵中的每个点map[i,j],把每个点和上一个点(mP[i-1][j])的Left和Right进行比较,
分别取最大和最小,Up则是上一个点的Up+1,进而求出面积进行比较。(参考此处)

维护三个二维数组,Left,Right,Up数组。
Left数组存储从map[i][j]这个点出发,满足条件能到达的最右边地方。
Right数组存储从map[i][j]这个点出发,满足条件能到达的最左边地方。
Up数组,直接存储从这点以上满足条件的能到达的最大长度。

 

•例题

① 洛谷P1169 传送门

悬线法裸题

需要注意的是最大正方形肯定是在最大长方形内部,以长方形的较短的边为边

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2005;
 4 int a[maxn][maxn];
 5 int l[maxn][maxn],r[maxn][maxn],up[maxn][maxn];
 6 int n,m;
 7 int s1,s2;
 8 void Slove()
 9 {
10      for(int i=1;i<=n;i++)
11         for(int j=2;j<=m;j++)//左边界 从左往右推
12             if(a[i][j]==(!a[i][j-1]))
13                 l[i][j]=l[i][j-1];
14 
15     for(int i=1;i<=n;i++)
16         for(int j=m-1;j>=1;j--)//右边界 从右往左推
17             if(a[i][j]==(!a[i][j+1]))
18                 r[i][j]=r[i][j+1];
19 
20     for(int i=1;i<=n;i++)
21     {
22         for(int j=1;j<=m;j++)
23         {
24             if(i>1&&a[i][j]==(!a[i-1][j]))
25             {
26                 up[i][j]=up[i-1][j]+1;
27                 l[i][j]=max(l[i][j],l[i-1][j]);
28                 r[i][j]=min(r[i][j],r[i-1][j]);
29             }
30             int len1=r[i][j]-l[i][j]+1;
31             int len2=up[i][j];
32             int curS=len1*len2;
33             s1=max(s1,curS);
34             //最大正方形肯定在长方形内部,以长方形短边为边长
35             s2=max(s2,min(len1,len2)*min(len1,len2));
36         }
37     }
38 }
39 
40 int main()
41 {
42     cin>>n>>m;
43     for(int i=1;i<=n;i++)
44     {
45         for(int j=1;j<=m;j++)
46         {
47             cin>>a[i][j];
48             l[i][j]=j;
49             r[i][j]=j;
50             up[i][j]=1;
51         }
52     }
53     Slove();
54     cout<<s2<<endl<<s1<<endl;
55 }
View Code

② Second Large Rectangle

传送门

  

原文地址:https://www.cnblogs.com/MMMinoz/p/11222439.html