C. Flag

目录

1.Problem

2.Input

3.Output

4.Examples

4.1input

4.2output

5.Code

6.Conclusion


1.Problem

Innokenty works at a flea market and sells some random stuff rare items. Recently he found an old rectangular blanket. It turned out that the blanket is split in n⋅mn⋅m colored pieces that form a rectangle with nn rows and mm columns.

The colored pieces attracted Innokenty's attention so he immediately came up with the following business plan. If he cuts out a subrectangle consisting of three colored stripes, he can sell it as a flag of some country. Innokenty decided that a subrectangle is similar enough to a flag of some country if it consists of three stripes of equal heights placed one above another, where each stripe consists of cells of equal color. Of course, the color of the top stripe must be different from the color of the middle stripe; and the color of the middle stripe must be different from the color of the bottom stripe.

Innokenty has not yet decided what part he will cut out, but he is sure that the flag's boundaries should go along grid lines. Also, Innokenty won't rotate the blanket. Please help Innokenty and count the number of different subrectangles Innokenty can cut out and sell as a flag. Two subrectangles located in different places but forming the same flag are still considered different.

 

 

These subrectangles are flags.

 

 

 

 

 

2.Input

The first line contains two integers nn and mm (1≤n,m≤10001≤n,m≤1000) — the number of rows and the number of columns on the blanket.

Each of the next nn lines contains mm lowercase English letters from 'a' to 'z' and describes a row of the blanket. Equal letters correspond to equal colors, different letters correspond to different colors.

3.Output

In the only line print the number of subrectangles which form valid flags.

4.Examples

4.1input

4 3
aaa
bbb
ccb
ddd

4.2output

6

5.Code

#include<bits/stdc++.h>

#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

int readint() {
    int x = 0, f = 1; 
    char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

const int MAXN = 1005;
char s[MAXN][MAXN];
int lst[MAXN][MAXN], bef[MAXN][MAXN], cnt[MAXN][MAXN][26];
ll ans;

int get(int x, int y, int d) {
    int l = 1, r = y + 1, mid, c = s[x][y] - 'a', ret = y + 1;
    while (l <= r) {
        mid = (l + r) / 2;
        if (cnt[x][y][c] - cnt[x - d][y][c] - cnt[x][mid - 1][c] + cnt[x - d][mid - 1][c] == (y - mid + 1) * d)
            ret = mid, r = mid - 1;
        else
            l = mid + 1;
    }
    return ret;
}

int main() {
    n = readint(); 
    m = readint();

    for (int i = 1; i <= n; i++) 
        scanf("%s", s[i] + 1);

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            for (int k = 0; k < 26; k++)
                cnt[i][j][k] = cnt[i][j - 1][k] + cnt[i - 1][j][k] - cnt[i - 1][j - 1][k] + (s[i][j] - 'a' == k);

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (s[i][j] == s[i - 1][j]) 
                lst[i][j] = lst[i - 1][j];
            else 
                lst[i][j] = i - 1;
        }
    }

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (lst[i][j] == lst[i][j - 1] && s[i][j] == s[i][j - 1]) 
                bef[i][j] = bef[i][j - 1];
            else 
                bef[i][j] = j - 1;
        }
    }

    int t1, t2, nx, tmp;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            t1 = lst[i][j], t2 = lst[t1][j], nx = max(bef[i][j], bef[t1][j]);
            if (i - t1 == t1 - t2 && t2 >= i - t1) {
                tmp = get(t2, j, i - t1) - 1;
                ans += j - max(nx, tmp);
            }
        }
    }

    cout << ans << endl;
    return 0;
}

6.Conclusion

这段代码的主要目的是计算一个二维字符数组 s 中满足一定条件的特殊矩形的数量。

具体而言,代码中有以下关键步骤:

  1. 通过 readint() 函数读取输入的行数 n 和列数 m
  2. 通过嵌套循环读取字符数组 s,并计算三维数组 cnt,表示每个位置之前出现的每个字符的数量。
  3. 计算二维数组 lst,表示每个位置上方与其相同字符的最近位置。
  4. 计算二维数组 bef,表示每个位置左侧与其相同字符的最近位置。
  5. 通过嵌套循环,对于每个位置 (i, j),计算特定条件下的矩形右上角的位置,并更新计数器 ans

这个代码涉及到二维数组的处理、前缀和的计算、二分查找,以及一些条件判断和计数等操作。整体而言,代码的目标是找到满足特定条件的矩形,并计算其数量,最后输出结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向阳而生__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值