B-躲藏(递推)-牛客小白月赛3

链接:https://www.nowcoder.com/acm/contest/87/B
来源:牛客网

题目描述
XHRlyb和她的小伙伴Cwbc在玩捉迷藏游戏。
Cwbc藏在多个不区分大小写的字符串中。
好奇的XHRlyb想知道,在每个字符串中Cwbc作为子序列分别出现了多少次。
由于Cwbc可能出现的次数过多,你只需要输出每个答案对2000120420010122取模后的结果。
聪明的你在仔细阅读题目后,一定可以顺利的解决这个问题!
输入描述:
输入数据有多行,每行有一个字符串。
输出描述:
输出数据应有多行,每行表示一个答案取模后的结果。
示例1
输入

Cwbc
输出

1
说明

Cwbc作为子序列仅出现了1次。
示例2
输入

acdcecfwgwhwibjbkblcmcnco
输出

81
说明

Cwbc作为子序列出现了34=81次。
备注:
每行字符串长度不超过2×105,字符串总长度不超过106。

[分析]
一开始觉得是dp,后来认真一想递推就行了。
因为字符串只有4个字母。
思路是这样的

记录cwbc出现的次数
但是有两个c所以需要处理一想

定义c1,w,b,c2记录出现次数,第一个c和最后一个分开
从头遍历到尾
遇到‘c’就c1++(其实还不止如此)
遇到‘w’就w+=c1 ,这样就得到了“cw”这个序列出现的次数(w的值)
遇到‘b’就b+=w ,这样就得到了“cwb”这个序列出现的次数(b的值)
这时候我们再来讨论最后的c
因为和第一个c一样所以要区别对待,但道理和w和b是一样的
遇到‘c’就c1++,并且c2+=b, 这样就得到“cwbc”这个序列出现的次数(c2的值)

输出c2就可以了

注意%2000120420010122

[代码]

#include<cstdio>
#include<cstring>
#define MOD 2000120420010122
char s[1000005];
int main()
{
    while (scanf("%s", s) != EOF)
    {
        int len = strlen(s);
        long long c1=0, w=0, b=0, c2=0;
        for (int i = 0; i < len; i++)
        {
            if (s[i] >= 'A'&&s[i] <= 'Z')s[i] = s[i] + 32;
            if (s[i] == 'c')
            {
                c1++;
                c2 = (c2 + (b%MOD)) % MOD;
            }
            else if (s[i]=='w')
            {
                w = (w + (c1%MOD)) % MOD;
            }
            else if (s[i] == 'b')
            {
                b = (b + (w%MOD)) % MOD;
            }
        }
        printf("%lld\n", c2%MOD);
    }
}

//cccwwwbbbccc
//   3699 27 27+27+27

猜你喜欢

转载自blog.csdn.net/q435201823/article/details/80295459