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;
}
posted @ 2021-06-25 21:09  Dazzling!  阅读(29)  评论(0编辑  收藏  举报