首先dp,
dp[ i ][ j] 表示以点(i,j)为右下角能取到的最大正方形的边长
点[ i ][ j ]被损坏,dp[i][j]=0, 否则dp[i][j]=min{ dp[ i-1 ][ j ] , dp[ i ][ j - 1] , dp[ i-1 ][ j-1 ] } + 1
扫描dp[ ][ ],记录答案输出即可
/*
ID:xsy97051
LANG:C++
TASK:range
*/
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
bool a[255][255];
int dp[255][255],cnt[255];
int main()
{
freopen("range.in","r",stdin);
freopen("range.out","w",stdout);
int n;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
char c;
cin>>c;
if(c=='1') a[i][j]=1;
}
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-1],min(dp[i-1][j],dp[i][j-1]))+1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=2;k<=dp[i][j];k++)
cnt[k]++;
for(int i=2;i<=n;i++)
if(cnt[i]!=0)
cout<<i<<" "<<cnt[i]<<endl;
return 0;
}