題目大意
- n*m的棋盤,每個格子有一個0/1的數值;
- 求一個最大的正方形子矩陣,要求矩陣內都是1;
- 輸出這個最大子矩陣的邊長;
題目分析
- 經典的子矩陣問題,問什麼設什麼:f[i][j]表示以(i,j)爲右下角的子矩陣,能構成正方形的邊長的最大值;
- 如果a[i][j]的值是0,f[i][j]不存在子矩陣;
- 如果a[i][j]的值是1,f[i][j]的值肯定與:左邊,上邊,左上,這三個格子的值有關;
- 如上圖,灰色和藍色格子都是已知的,則橙色格子的值,只受到藍色格子的影響;
- 因爲橙色格子所在的子矩陣,需要同時包涵三個藍色的格子,所以三個藍色格子中的最小值+1,就是橙色格子的f值;
思路
- 因爲求最大子矩陣,所以過程中更新一下ans,得到答案;
思路1參考代碼
//luogu1387:最大正方形
#include<bits/stdc++.h>
using namespace std;
int a[110][110];
int f[110][110];
int n,m,ans;
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
if(a[i][j])
{
f[i][j]=min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1])+1;
ans=max(ans,f[i][j]);
}
}
}
printf("%d",ans);
return 0;
}