zoukankan      html  css  js  c++  java
  • 悬线法

    悬线法

     

    •用途

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

    •思路

    悬线法是一条竖线,这条竖线要满足上端点在整个矩形上边界或者是一个障碍点。
    然后以这条悬线进行左右移动,直到移至障碍点或者是矩阵边界,进而确定这条悬线所在的极大矩阵。
    也就是说,我们要针对矩阵中每个点进行求极大矩阵的操作,
    所以我们需要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

    传送门

      

  • 相关阅读:
    springboot 集成RabbitMQ
    服务接口API限流 Rate Limit 续
    服务接口API限流 Rate Limit
    聊下并发和Tomcat线程数
    java 线程池 异步任务
    Tomcat中更改网站根目录和默认页的配置方法
    QPS从0到4000请求每秒,谈达达后台架构演化之路
    分布式与集群是什么 ? 区别是什么?
    大型网站技术架构演变总结
    提升高并发量服务器性能解决思路
  • 原文地址:https://www.cnblogs.com/MMMinoz/p/11222439.html
Copyright © 2011-2022 走看看