2019 가축 오프 더 학교 여덟 번째 필드 A를 모든-한 행렬

링크 : https://ac.nowcoder.com/acm/contest/888/A 출처 : 가축 오프 네트워크

제목 설명

Gromah 및 LZR들은 처음 보는 것은 m × : 백만 미네소타 \ 시간 × N 크기의 행렬이며, 큰 묘를 입력하고, 행렬의 요소가 모두 0 또는 1이다.

LZR는 모두 하나의 행렬 요소가 모두 11 _ {} 1, 완전히 다른 모든 -에 의해 포함되지 않습니다 주어진 행렬의 모든 하나의 서브 매트릭스의 수를 결정해야 행렬로 정의된다 "라는 메모 보드를 찾습니다 하나의 서브 매트릭스 ".

한편, Gromah 또한 암호 잠금 발견, 분명히 암호를 메모 보드에 언급 된 수 있어야한다!

그 암호를 결정하는 데 도움이하고 다음 단계를 입력하십시오.

설명을 입력합니다 :

The first line contains two positive integers n,mn,m_{}n,m, denoting the size of given matrix.Following nn_{}n lines each contains a string with length mm_{}m, whose elements are all 00_{}0 or 11_{}1, denoting the given matrix.1≤n,m≤30001\le n,m \le 30001≤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).

생각

먼저 각 고려 \ (1 \) 상황이 답변 기여를 생산하는 것이 무엇에서 그리드를.

쉽게 얻을 수 : 그리드의 오른쪽 하단 모서리에 답을 ​​생산하는 큰 모든 사각형 한 기여가있는 경우.

따라서, 우리는 각 열 접두사, 좋은 전체 사각형의 마지막 행으로 각 행을 열거하고 지속적으로 유지하기 위해 추구 할 수 있습니다 \ (1 \) 수입니다.

단조 엄격한 단조로운 스택을 유지 및 증가 가장 왼쪽의 도달 위치를 유지하고, 각 위치를 열거하면.

포인트 때 \ ((I, J)는 \ ) 때 기부 발생 대답 \ ((I + 1, J)가 \) 반드시 (0 \) \ , 및 높이 미만 (I-1, J)를 높이입니다.

암호

#include <bits/stdc++.h>

using namespace std;
const int maxn = 3010;
typedef pair<int,int> pii;
int mp[maxn][maxn], 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", &mp[i][j]);
    }

    for (int j=1; j<=m; ++j) {
        for (int i=1; i<=n; ++i) {
            if(mp[i][j])
                mp[i][j] = mp[i-1][j]+1;
        }
    }

//    for (int i=1; i<=n; ++i) {
//        for (int j=1; j<=m; ++j)
//            printf("%d", mp[i][j]);
//        puts("");
//    }

    int ans = 0;
    for (int i=1; i<=n; ++i) {
        pii sta[maxn];
        int top=0, r=-1;
        for (int j=1; j<=m+1; ++j) {
            int pos=j;
            while(top && sta[top].first > mp[i][j]) {
                if(sta[top].second <= r) ++ans;
                pos = sta[top--].second;
            }
            if(!mp[i+1][j]) r = j;
            if(mp[i][j] && (!top || sta[top].first<mp[i][j])) sta[++top] = {mp[i][j], pos};
        }
    }
    printf("%d\n", ans);
    return 0;
}

추천

출처www.cnblogs.com/acerkoo/p/11334649.html