zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第八场)A:All-one Matrices(广告牌问题 单调队列)

    题意:给出N*M的01矩阵,求矩阵个数,满足矩阵内全是‘1’,,而且被至少一个’0‘围住。(假设边界外是‘0’。(N,M<3000)
    思路:这类问题,一般解决就是两个方向:

        A:压缩一维,即枚举上下边界,然后复杂度O(N^3);

        B:广告牌问题,即枚举下边界s,那么久可以看成s为底的一些高楼,再高楼上布置广告牌,复杂度O(N^2)。

    显然这里是B类问题。 那么B方法来做,还有两个问题需要处理:

        1:去重。   方法应该有很多,这里用的是:(L,R)出现次数的唯一的,直接vis[L][R]即可。

        2:如果底下全是‘1’,则不合法。

    去重的话,加个vis数组,给个时间戳就可以了。   不合法的话,等效于底下全是1,预处理底下的前缀和即可。

    (我也不知道为什么过得这么少啊...

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=3010;
    char c[maxn][maxn];
    int M,h[maxn][maxn],ans,L[maxn],R[maxn],num[maxn],vis[maxn][maxn];
    int q[maxn],head;
    void get(int t)
    {
        head=0; q[++head]=0;
        rep(j,1,M) {
            while(head>0&&h[t][j]<=h[t][q[head]]) head--;
            L[j]=q[head]+1;
            q[++head]=j;
        }
        head=0; q[++head]=M+1;
        for(int j=M;j>=1;j--) {
            while(head>0&&h[t][j]<=h[t][q[head]]) head--;
            R[j]=q[head]-1;
            q[++head]=j;
        }
        rep(i,1,M) num[i]=num[i-1]+(c[t+1][i]=='1');
        rep(i,1,M){
            if(h[t][i]==0) continue; 
            if(vis[L[i]][R[i]]==t) continue; //去重
            if(num[R[i]]-num[L[i]-1]==R[i]-L[i]+1) continue; //去不合法
            ans++;
            vis[L[i]][R[i]]=t;
        }
    }
    int main()
    {
        int N;
        scanf("%d%d",&N,&M);
        rep(i,1,N) scanf("%s",c[i]+1);
        rep(i,1,N)
         rep(j,1,M){
             if(c[i][j]=='0') h[i][j]=0;
             else h[i][j]=h[i-1][j]+1;
        }
        rep(i,1,N) get(i);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    body标签相关
    前端基础
    26,进程
    网络编程基础socket 重要中:TCP/UDP/七层协议
    24,内置方法的应用,(实现单利模式)
    23,反射,内置方法。
    22,hashlib(md5,和,sha算法)logging日志模块
    21,钻石继承,多态,封装,几个装饰器函数
    20,序列化模块 json,pickle,shelve
    19,面向对象
  • 原文地址:https://www.cnblogs.com/hua-dong/p/11332063.html
Copyright © 2011-2022 走看看