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

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 !
评论
  目录