动态规划
f[i][j]表示 (i,j)为右下角,所围成的最大正方形
up[i][j] (i,j) 上方有多少连续的区域
left[i][j] (i,j)左边有多少连续的区域
up[i][j] = up[i - 1][j] + 1 或者为0
left[i][j] = left[i][j - 1] +1或者为0
f[i][j] = min(f[i - 1][j - 1], up[i][j], left[i][j]) + 1
#include <cstdio>
const int savebuff = 10;
const int max_n = 250 + savebuff;
int f[max_n][max_n]={0}, up[max_n][max_n]={0}, left[max_n][max_n]={0};
int ans[max_n]={0};
int n;
char a[max_n][max_n];
inline int min(int a, int b)
{
if (a < b) return a;
return b;
}
inline int min(int a, int b, int c)
{
return min(min(a, b), c);
}
int main()
{
scanf("%d\n", &n);
for (int i = 1; i <= n; ++ i) gets(a[i] + 1);
for (int i = 1; i <= n; ++ i)
for (int j = 1; j <= n; ++ j)
{
if (a[i][j] == '1')
{
up[i][j] = up[i - 1][j] + 1;
left[i][j] = left[i][j - 1] + 1;
f[i][j] = min(f[i - 1][j - 1] + 1, up[i][j], left[i][j]);
++ans[f[i][j]];
}
}
for (int i = n - 1; i >= 2; -- i) ans[i] += ans[i + 1];
for (int i = 2; i <= n; ++ i)
if (ans[i]) printf("%d %d\n", i, ans[i]);
return 0;
}