https://www.luogu.org/problemnew/show/2733
dp[i][j]=min(dp[i−1][j],dp[i][j−1],dp[i−1][j−1])+1(a[i][j]=1)
其中
dp[i][j]
表示从左上角到(i,j)的最大正方形长度。
这题小正方形还会在大正方形里,所以还要再加上它们。
下面的程序读入好像有点问题..
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 251;
int n,a[maxn][maxn],dp[maxn][maxn],count[maxn];
int main(){
scanf("%d",&n);getchar();
for(int i =1;i<=n;i++){
for (int j =1,c;j<=n;j++){
c = getchar();
if (c=='1'){
a[i][j] = 1;
}else if (c=='0'){
a[i][j] = 0;
}
}
getchar();
}
memset(count,0,sizeof(count));
//if (a[1][1]==true) dp[1][1] = 1;else dp[1][1] = 0;
for (int i =1;i<=n;i++)
for(int j =1;j<=n;j++){
if (a[i][j]){
dp[i][j] = min(dp[i-1][j],min(dp[i][j-1],dp[i-1][j-1]))+1;
count[dp[i][j]]++;
}
}
for (int i = n;i>=2;i--){
count[i-1] += count[i];//从后往前遍历,不用考虑一个正方形可以放几个小正方形
}
for (int i = 2;i<=n;i++){
if (count[i]!=0) cout<<i<<" "<<count[i]<<endl;
}
}