题目描述
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 1≤n,m≤3000
输出描述:
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);
}