zoukankan      html  css  js  c++  java
  • 2019牛客多校第二场H题(悬线法)

    把以前的题补补,用悬线求面积第二大的子矩形。我们先求出最大子矩阵的面积,并记录其行三个方向上的悬线长度。然后排除这个矩形,记得还得特判少一行或者少一列的情况

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e3+10;
    int n;
    int mat[maxn][maxn],Left[maxn][maxn],Right[maxn][maxn],up[maxn][maxn];
    
    int main()
    {
        int T;
        T=1;
        while(T--)
        {
            int m,n;
            cin>>m>>n;
            for(int i=0;i<m;i++)
            {
                for(int j=0;j<n;j++)
                {
                    char ch;
                    cin>>ch;
                    mat[i][j]=ch=='1'?0:1;
                }
            }
            int ans=0,max2=0,l,r,u,b;
            for(int i=0;i<m;i++)
            {
                int lo=-1,ro=n;
                for(int j=0;j<n;j++)
                {
                    if(mat[i][j]==1)
                    {
                        up[i][j]=Left[i][j]=0;lo=j;
                    }
                    else
                    {
                        up[i][j]=i==0?1:up[i-1][j]+1;
                        Left[i][j]=i==0?lo+1:max(Left[i-1][j],lo+1);
                    }
                }
                for(int j=n-1;j>=0;j--)
                {
                    if(mat[i][j]==1)
                    {
                        Right[i][j]=n;ro=j;
                    }
                    else
                    {
                        Right[i][j]=i==0?ro-1:min(Right[i-1][j],ro-1);
                        if(ans<(up[i][j]*(Right[i][j]-Left[i][j]+1)))
                        {
                            ans=up[i][j]*(Right[i][j]-Left[i][j]+1);
                            u=up[i][j],l=Left[i][j],r=Right[i][j],b=i;
                         } 
                    }
                }
            }
            max2=max(max2,u*(r-l));
            max2=max(max2,(u-1)*(r-l+1)); 
            for(int i=0;i<m;i++)
            {
                int lo=-1,ro=n;
                for(int j=0;j<n;j++)
                {
                    if(mat[i][j]==1)
                    {
                        up[i][j]=Left[i][j]=0;lo=j;
                    }
                    else
                    {
                        up[i][j]=i==0?1:up[i-1][j]+1;
                        Left[i][j]=i==0?lo+1:max(Left[i-1][j],lo+1);
                    }
                }
                for(int j=n-1;j>=0;j--)
                {
                    if(mat[i][j]==1)
                    {
                        Right[i][j]=n;ro=j;
                    }
                    else
                    {
                        Right[i][j]=i==0?ro-1:min(Right[i-1][j],ro-1);    
                        if(u==up[i][j]&&l==Left[i][j]&&r==Right[i][j]&&b==i)
                        continue;
                        if(max2<(up[i][j]*(Right[i][j]-Left[i][j]+1)))
                        {
                            max2=up[i][j]*(Right[i][j]-Left[i][j]+1);
                            
                         } 
                    }
                }
            }
            cout<<max2<<"
    ";
         } 
        return 0;
    }
  • 相关阅读:
    IT资产管理系统SQL版
    反转单词(C#实现)
    删除数组中重复的元素(C#实现)
    最大子数组之和(C#实现)
    判断是否是三角形
    如何解决SSAS + SSRS + WSS3.0 之间的Windows 集成验证问题
    关于SharpDevelop
    规划一个SharePoint的解决方案
    Scalability Design
    合作意味着分享
  • 原文地址:https://www.cnblogs.com/hh13579/p/11674912.html
Copyright © 2011-2022 走看看