嘘~ 正在从服务器偷取页面 . . .

CF1393D Rarity and New Dress 题解


CF1393D Rarity and New Dress 题解

题目链接:CF1393D Rarity and New Dress

题意:

cxy 要从一块 $n\times m$ 的布料上裁一块菱形做裙子(不是给自己做。

这一块布料由 $n\times m$ 个颜色块组成,要满足裁下的菱形必须由若干相同的颜色块组成。

求有多少种裁法。

注:一个方格也算一个菱形。

Examples of proper dress patterns: Examples of improper dress patterns: The first one consists of multi-colored scraps, the second one goes beyond the bounds of the piece of fabric, the third one is not a square with sides forming a $45^{\circ}$ angle with sides of the piece of fabric.

Rarity wonders how many ways to cut out a dress pattern that satisfies all the conditions that do exist. Please help her and satisfy her curiosity so she can continue working on her new masterpiece!

输入格式:

The first line contains two integers $n$ and $m$ ( $1\le n, m \le 2000$ ). Each of the next $n$ lines contains $m$ characters: lowercase English letters, the $j$ -th of which corresponds to scrap in the current line and in the $j$ -th column. Scraps having the same letter share the same color, scraps having different letters have different colors.

输出格式:

Print a single integer: the number of ways to cut out a dress pattern to satisfy all of Rarity’s conditions.

看上去很难,其实很简单。我们只需要找到所有极大的菱形就可以了,

而每个菱形都可以由中心和直径决定,因此考虑维护每个点最远能到哪,稍微算算就好啦。

时间复杂度 $\mathcal{O}(nm)$

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
#define N ((int)(2e3 + 15))

char c[N][N];
int n,m,ans,U[N][N],D[N][N],L[N][N],R[N][N];
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> (c[i] + 1);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            U[i][j] = (c[i][j] == c[i - 1][j] ? U[i - 1][j] + 1 : 1);
    for(int i = n; i >= 1; i--)
        for(int j = 1; j <= m; j++)
            D[i][j] = (c[i][j] == c[i + 1][j] ? D[i + 1][j] + 1 : 1);
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
            if(c[i][j] != c[i][j - 1]) L[i][j] = 1;
            else L[i][j] = min({U[i][j], D[i][j], L[i][j - 1] + 1});
        for(int j = m; j >= 1; j--)
            if(c[i][j] != c[i][j + 1]) R[i][j] = 1;
            else R[i][j] = min({U[i][j], D[i][j], R[i][j + 1] + 1});
        for(int j = 1; j <= m; j++) ans += min(L[i][j], R[i][j]);
    }
    cout << ans << '\n';
    return 0;
}

文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录