2019牛客多校训练营(第八场)———A

原题题址

题目描述

Gromah and LZR entered the great tomb, the first thing they see is a matrix of size n × m n\times m n×m, and the elements in the matrix are all 0 0_{} 0​ or 1 1_{} 1​.
LZR finds a note board saying “An all-one matrix is defined as the matrix whose elements are all 1 1_{} 1​​, you should determine the number of all-one submatrices of the given matrix that are not completely included by any other all-one submatrices”.
Meanwhile, Gromah also finds a password lock, obviously the password should be the number mentioned in the note board!
Please help them determine the password and enter the next level.

Gromah和LZR进入了大墓,他们首先看到的是一个尺寸为n×m的矩阵,矩阵中的元素都是 0 0_{} 0 1 1_{} 1
LZR发现一个注释板,上面写着“一个所有一个矩阵被定义为其元素都是 1 1_{} 1的矩阵,您应该确定给定矩阵中所有未被任何其他所有一个子矩阵完全包含的子矩阵的数量”。
同时,格罗马还发现了一个密码锁,显然密码应该是记事本上提到的数字!
请帮助他们确定密码并输入下一级别。
输入描述:

The first line contains two positive integers n n_{} n, m m_{} m​, denoting the size of given matrix

第一行包含两个正整数 n n_{} n, m m_{} m​,表示给定矩阵的大小。

Following n n_{} n​ lines each contains a string with length mm_{}m​, whose elements are all 0 0_{} 0 or 1 1_{} 1​, denoting the given matrix.

接下来 n n_{} n行,每行包含一个长度为 m m_{} m的字符串,其元素都是 0 0_{} 0 1 1_{} 1 ​,表示给定的矩阵。

1 ≤ n , m ≤ 3000 1\le n,m \le 3000 1n,m3000

输出描述:

Print a non-negative integer, denoting the answer.

示例1

输入

3 4
0111
1110
0101

输出

5

说明

The 5 matrices are (1,2)−(1,4),  (1,2)−(2,3),  (1,2)−(3,2),  (2,1)−(2,3),  (3,4)−(3,4)

介个题目的解法我个人觉得不简单前缀和+单调栈,但是因为相似的题目写过几次,所以应该还是不能说难。

#include <stdio.h>
#include <stack>
using namespace std;
char s[3005][3005];
int MatrixBottom[3005][3005],up[3005],N,M,ans = 0;//MatrixBottom是存最后跟新长度为L~R的底边位置,up存当前行为底边的直方图的高
int main() {
    scanf("%d%d", &N, &M);
    for (int i = 1; i <= N; i++) {        
    scanf("%s", s[i]); 
    }    
    for(int i = 1; i <= N; i++) { 
        for(int j = 0; j < M; j++) {     
               if(s[i][j] == '0')     
                up[j] = 0; 
               else               
               up[j]++;        
       }     
     stack<int> S;    
     for(int j = 0; j <= M; j++) {       
          while(!S.empty() && up[S.top()] > up[j]) {           
               int t = S.top();                
               S.pop();                
               int l;           
               while(!S.empty() && up[S.top()] == up[t]) S.pop();                     
               if(S.empty()) l = 0;                
               else l = S.top() + 1;               
               if(i == 0)  ans++;                
               else if(MatrixBottom[l][j - 1] != i) ans++;                
               MatrixBottom[l][j - 1] = i + 1;            
          }            
          S.push(j);        
       }  
    }   
    printf("%d\n", ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值