Description
We often use the matrix to analyze reality models. There are lots of algorithm about matrix in Linear Algebra like matrix multiplication, matrix determinant and matrix inversion, etc.
Recently, I should use matrix to do structural mechanics analysis. The element in the matrix indicating the mechanical properties of each unit in the structure. Stable sub-structure means a part with same mechanical properties. I want to find the largest stable sub-struture as it has good engineering applications. Reflected in the matrix, the problem above equals to find the largest sub-matrix whose members have the same value.
To accomplish the task perfectly, I wish you can help me to design a good algorithm to solve this problem.
Input
There are multiple test cases.
The first line contains two integers N and M, indicating the size of this N * M matrix A.
The next N line, each line containing M integers. The j-th integer in the i-th line means the element A(i, j).
1 <= N, M <= 800
1 <= A(i, j) <= 1000
Output
For each test, output the size of the largest sub-matrix satisfied the requests.
Sample Input
Sample Output
HINT
Source
Solution
单调栈
Implementation
#include <cstdio> #include <stack> using namespace std; typedef long long LL; const int N(800+5); int h[N], L[N], R[N], a[N][N]; stack<int> st; //[L[i], R[i]) int mono_stack(int l, int r){ for(; st.size(); st.pop()); for(int i=l; i<r; i++){ for(; !st.empty()&&h[st.top()]>=h[i]; st.pop()); if(st.empty()) L[i]=l; else L[i]=st.top()+1; st.push(i); } for(; st.size(); st.pop()); for(int i=r-1; i>=l; i--){ for(; !st.empty() && h[st.top()]>=h[i]; st.pop()); if(st.empty()) R[i]=r; else R[i]=st.top(); st.push(i); } int res=0; for(int i=l; i<r; i++) res=max(res, h[i]*(R[i]-L[i])); return res; } void solve(int n, int m){ int res=0; for(int i=0; i<n; i++){ if(i==0) for(int j=0; j<m; j++) h[j]=1; else for(int j=0; j<m; j++) if(a[i][j]==a[i-1][j]) h[j]++; else h[j]=1; //two-pointers for(int l=0, r; l<m; l=r){ for(r=l+1; r<m && a[i][r]==a[i][l]; r++); res=max(res, mono_stack(l, r)); } } printf("%d ", res); } int main(){ for(int n, m; ~scanf("%d%d", &n, &m); ){ for(int i=0; i<n; i++) for(int j=0; j<m; j++) scanf("%d", a[i]+j); solve(n, m); } return 0; }