ICPC Northeastern European Regional Contest 2019 签到题-B.Balls of Buma

链接:https://www.jisuanke.com/contest/10453/challenges

Balph is learning to play a game called Buma. In this game, he is given a row of colored balls. He has to choose the color of one new ball and the place to insert it (between two balls, or to the left of all the balls, or to the right of all the balls).

When the ball is inserted the following happens repeatedly: if some segment of balls of the same color became longer as a result of a previous action and its length became at least 3 3 3, then all the balls of this segment are eliminated.

Consider, for example, a row of balls AAABBBWWBB. Suppose Balph chooses a ball of color W and the place to insert it after the sixth ball, i.~e. to the left of the two Ws. After Balph inserts this ball, the balls of color W are eliminated, since this segment was made longer and has length 3 3 3 now, so the row becomes AAABBBBB . The balls of color B are eliminated now, because the segment of balls of color B became longer and has length 5 5 5 now. Thus, the row becomes AAA . However, none of the balls are eliminated now, because there is no elongated segment.

Help Balph count the number of possible ways to choose a color of a new ball and a place to insert it that leads to the elimination of all the balls.

输入格式

The only line contains a non-empty string of uppercase English letters of length at most 3 ⋅ 1 0 5 3·10^5 3105. Each letter represents a ball with the corresponding color.

输出格式

Output the number of ways to choose a color and a position of a new ball in order to eliminate all the balls.

样例

input
BBWWBB
output
3
input
BWWB
output
0
input
BBWBB
output
0

题意

给你一个字符串,让你玩开心消消乐
如果你插入一个字符后,使字符串中的一段字符既是同一种字符,又增长该段字符的长度,同时该段字符长度大于三,你就可以将这一段的相同字符消去,剩余的字符继续合并成一个字符串。在合并之后,如果依然可以出现上述一类的字符段,则可以继续消去。直到字符串完全消失。
问可以有多少插入的方式使该字符段完全消失。

思路

在理解题意后,我们可以发现只有当字符段(指连续的相同字符的字符段)的数量为奇数,字符段类似回文的对称,且在插入和合并之后都可以满足消去消去条件的字符串才可能有完全消除的可能,否则输出 0 0 0
当给定字符串有消除的可能后,可以插入的方式即为中心字符段可以插入的位置,所以输出最中间字符段长度+ 1 1 1即可。

实现方法:

  • 用结构体 s t r str str存放一个字符段的字符种类和段长度。
  • 用不定长数组 q q q依次存放每个 s t r str str
  • 从两端向中间搜索,不满足字符段字符相同且段长度和大于 3 3 3时,提前退出搜索。
  • 完全满足消去条件,输出中心字符段长度+ 1 1 1,否则输出 0 0 0

时间复杂度 O ( 3 2 n ) O(\frac{3}{2}n) O(23n)
蒟蒻自己瞎算的复杂度T^T
在这里插入图片描述

code

/*
 * @Autor: CofDoria
 * @Date: 2020-08-17 17:10:55
 * @LastEditTime: 2020-09-02 14:21:18
 */
#include <bits/stdc++.h>
using namespace std;

#define db double
#define ll long long
#define inf 0x3f3f3f3f
#define s(a, n) memset(a, n, sizeof(a))
#define debug(a) cout << '#' << a << '#' << endl
#define rep(l, a, b) for (register ll l = a; l < b; ++l)
#define per(l, a, b) for (register ll l = a; l >= b; --l)
#define _ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define _forit(i, c) \
    for (__typeof__((c).begin()) i = (c).begin(); i != (c).end(); ++i)

bool fi = true;
const unsigned long long MOD = 1e9 + 7;

inline ll gcd(ll a, ll b) { return (b == 0 ? a : gcd(b, a % b)); }

struct str {
    char c;
    int len;
};

vector<str> q;

int main() {
    _ios;
    char s[300005];
    cin >> s;
    int sz = strlen(s), l = 1;
    char sc = s[0];
    rep(i, 1, sz + 1) {
        if (s[i] != sc) {
            str a;
            a.c = sc;
            a.len = l;
            q.push_back(a);
            l = 1;
            sc = s[i];
            continue;
        }
        l++;
    }
    sz = q.size();
    // debug(sz);
    if (sz & 1) {
        int sz2 = sz / 2;
        rep(i, 0, sz2) {
            // debug(' ');
            // debug(q[i].c);
            // debug(q[sz - 1 - i].c);
            // debug(q[i].len);
            // debug(q[sz - 1 - i].len);
            if (q[i].c == q[sz - 1 - i].c &&
                q[i].len + q[sz - 1 - i].len >= 3) {
                continue;
            }
            printf("0");
            return 0;
        }
        if (q[sz2].len >= 2) {
            printf("%d", q[sz2].len + 1);
            return 0;
        }
        printf("0");
        return 0;
    }
    printf("0");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值