题目大意:
有一个0,1矩阵。求其中的0,1交错的最大子正方形矩阵和长方形矩阵的面积。
解题思路:
求这种最大子矩阵的题目很可能是悬线法。
这个矩阵某个格子[i,j] 向左可能延伸到多远,向右可能延伸到多远,向上可能延伸到多远,然后在确定纵向可以向下延伸时候利用转移公式:
up[i][j] = up[i-1][j]+1
left[i][j] = max(left[i-1][j].left[i][j])
right[i][j]=min(right[i-1][j],right[i][j])
i,j分别代表行和列。left和right表示向左或者向右延伸到多远。然后(right[i][j]-left[i][j])*height[i][j],即可以得到子矩阵的面积大小。
注意初始化:
left[i][j]=right[i][j]=j;
up[i][j]=1
在确定可以向左延伸时候
left[i][j] = left[i][j-1]
在确定可以向右延伸时候
right[i][j] = right[i][j+1]
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,m;cin>>n>>m;
int chess[n][m];
int lf[n][m];
int rg[n][m];
int up[n][m];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
cin>>chess[i][j];
lf[i][j]=j;
rg[i][j]=j;
}
for(int i=0;i<n;i++)
for(int j=1;j<m;j++){
if(chess[i][j]!=chess[i][j-1]){
lf[i][j]=lf[i][j-1];
}
}
for(int i=0;i<n;i++)
for(int j=m-2;j>=0;j--){
if(chess[i][j]!=chess[i][j+1])
rg[i][j]=rg[i][j+1];
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
up[i][j]=1;
}
int ans1=1;
int ans2=1;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
if(i>0 && chess[i][j]!=chess[i-1][j]){
lf[i][j]=max(lf[i][j],lf[i-1][j]);
rg[i][j]=min(rg[i][j],rg[i-1][j]);
up[i][j]=up[i-1][j]+1;
}
//cerr<<i<<" "<<j<<" "<<lf[i][j]<<" "<<rg[i][j]<<" "<<up[i][j]<<endl;
int len=rg[i][j]-lf[i][j]+1;
int sqlen=min(len,up[i][j]);
ans1=max(ans1,sqlen*sqlen);
ans2=max(ans2,up[i][j]*len);
}
cout<<ans1<<endl;
cout<<ans2<<endl;
return 0;
}