• 2019牛客多校2 H Second Large Rectangle(悬线法)


    题意:

    求第二大子矩形

    思路:

    设最大子矩形x*y,第二大子矩形一定在一下情况中

    (x-1)*y

    x*(y-1)

    其他最大子矩形候选者

    注意去重手法

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    //#include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
         
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
     
    using namespace std;
     
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
     
    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 1e4+100;
    const int maxm = 2e6+100;
    const int inf = 0x3f3f3f3f;
    //const db pi = acos(-1.0);
     
    int a[1111][1111];
    int l[1111][1111];
    int r[1111][1111];
    multiset<int>ans;
    int h[1111][1111];
    int lft[1111][1111];
    int rt[1111][1111];
    int n, m;
    
    int main(){
        scanf("%d %d" ,&n, &m);
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                scanf("%1d",&a[i][j]);
            }
        }
        for(int i = 1; i <= n; i++){
            int tmp = 0;
            for(int j = 1; j <= m; j++){
                if(a[i][j]==0)tmp=j;
                lft[i][j]=tmp;
            }
            tmp=m+1;
            for(int j = m; j >= 1; j--){
                if(a[i][j]==0)tmp=j;
                rt[i][j]=tmp;
            }
        }
           PI mx=make_pair(-1,-1);
           int up = -1;
           int mxs = 0;
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                if(i==1||a[i-1][j]==0)h[i][j]=1;
                else h[i][j]=h[i-1][j]+1;
                if(h[i][j]==1){
                    l[i][j] = lft[i][j];
                    r[i][j] = rt[i][j];
                }
                else{
                    l[i][j] = max(l[i-1][j],lft[i][j]);
                    r[i][j] = min(r[i-1][j], rt[i][j]);
                }
                if(a[i][j]==0)continue;
                int res = (r[i][j]-l[i][j]-1)*h[i][j];
                if(res>mxs){
                    mxs=res;
                    mx = make_pair(i,j);up=i-h[i][j]+1;
                }
            }
        }
        int ans = max((r[mx.fst][mx.sc]-l[mx.fst][mx.sc]-1)*(h[mx.fst][mx.sc]-1),(r[mx.fst][mx.sc]-l[mx.fst][mx.sc]-2)*h[mx.fst][mx.sc]);
        //printf("%d
    ",ans);
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                if(l[i][j]==l[mx.fst][mx.sc]&&r[i][j]==r[mx.fst][mx.sc]&&i-h[i][j]+1==up)continue;
                int sum = (r[i][j]-l[i][j]-1)*h[i][j];
                if(sum>ans){
                    ans=sum;
                }
            }
        }
        printf("%d",ans);
        return 0;
    }
    /*
    1 2
    11
    3 3
    110
    111
    011
    3 3
    111
    011
    011
    1 4
    1011
    3 4
    1101
    0111
    1111
    7 8
    11110000
    11110000
    00000111
    01110111
    01110111
    01110000
    00000000
    4 4
    1111
    1111
    1111
    1111
    3 3
    111
    010
    010
    2 6
    010011
    001111
    3 3
    011
    111
    111
     */
  • 相关阅读:
    Linux 设备驱动 Edition 3(中文版)
    内核和用户空间共享内存的实现例程proc和mmap
    mmap的详细使用(用户空间)
    使用 I/O 内存from LDD3
    关于strcpy、memset、memcpy的使用详解
    get_free_page 和其友
    Linux调试技术介绍
    关于信息时代的学习
    [恢]hdu 1196
    [恢]hdu 1157
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/11260147.html
Copyright © 2020-2023  润新知