• 牛客网多校训练第八场A All one Matrix


    题目链接:https://ac.nowcoder.com/acm/contest/888/A

    题意:求出有多少个不被包含的全1子矩阵

    解题思路:首先对列做处理,维护每个位置向上1的个数,然后我们从最后一行开始处理(方便去重),通过单调栈维护每个点左右第一个小于它的值的下标l[j],r[j],那么(l[j]-1,r[j]-1)就是以当前行为矩阵底的左右边界(左右无法再扩展,向上也不能),我们只需维护当前左右边界相同的矩阵,上一次所覆盖到的矩阵上边界,如果这个矩阵底所在行小于前一个相同左右边界矩阵的上边界所在行,那么这两个矩阵就是不存在包含关系的,ans++

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 3005;
    int a[N][N],l[N],r[N],last[N][N];
    int main() {
        int n, m;
        scanf("%d%d", &n, &m);
        memset(last,0x3f, sizeof(last));
        getchar();
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)a[i][j] = getchar() == '0' ? 0 : a[i - 1][j] + 1;
            getchar();
        }
        int sta[N],top=0;
        int ans=0;
        for (int i = n; i >= 1; i--)
        {
            top=0,sta[0]=0;
            for(int j=1;j<=m;j++)
            {
                while (top&&a[i][sta[top]]>=a[i][j])top--;
                l[j]=sta[top];
                sta[++top]=j;
            }
            top=0,sta[0]=m+1;
            for(int j=m;j>=1;j--)
            {
                while (top&&a[i][sta[top]]>=a[i][j])top--;
                r[j]=sta[top];
                sta[++top]=j;
            }
            for(int j=1;j<=m;j++)
            {
                if(a[i][j]&&i<last[l[j]+1][r[j]-1])//i要小于上次统计过的同左右边界矩阵的上边界
                {
                    ans++;
                    last[l[j]+1][r[j]-1]=i-a[i][j]+1;//记录当前统计矩阵的上边界
                }
            }
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    Ngui使用随心记
    Ngui分辨率适配
    最大堆(优先队列)
    循环队列 & 栈的共用空间
    C#顺序表 & 单向链表(无头)
    IntelliJ Idea 常用快捷键列表
    写增删改查遇到的小问题总结
    用JS解决html页面间获取context-path问题
    html 页面如何获得url中的参数
    @RequestBody和@RequestParam区别
  • 原文地址:https://www.cnblogs.com/xusirui/p/11347094.html
Copyright © 2020-2023  润新知