1387. 家的范围
枚举求得各种边长的正方形的数目。
const int N = 255;
char s[N][N];
int f[N][N];
int cnt[N];
int n;
int main()
{
cin >> n;
for(int i = 1; i <= n; i++) cin >> s[i] + 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(s[i][j] == '1')
{
f[i][j] = min(f[i - 1][j], min(f[i][j - 1], f[i - 1][j - 1])) + 1;
for(int k = 2; k <= f[i][j]; k++)
cnt[k]++;
}
for(int i = 2; cnt[i]; i++)
cout << i << ' ' << cnt[i] << endl;
//system("pause");
return 0;
}
f[i][j] 表示以 (i, j) 为右下角的正方形的最大边长,那么除此定义之外,f[i][j] = x 也表示以 (i, j) 为右下角的正方形的数目为 x(即边长为 1, 2, ..., x 的正方形各一个)。在计算出每种 f[i][j] 的个数后,我们通过后缀和就可以得到每种边长的正方形的数目。
const int N = 255;
char s[N][N];
int f[N][N];
int cnt[N];
int n;
int main()
{
cin >> n;
for(int i = 1; i <= n; i++) cin >> s[i] + 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(s[i][j] == '1')
{
f[i][j] = min(f[i - 1][j], min(f[i][j - 1], f[i - 1][j - 1])) + 1;
cnt[f[i][j]]++;
}
for(int i = n; i; i--) cnt[i] += cnt[i + 1];
for(int i = 2; cnt[i]; i++)
cout << i << ' ' << cnt[i] << endl;
//system("pause");
return 0;
}