寒假每日一题-FEB

题目

有一个长度为 N 的字符串 S,其中的每个字符要么是 B,要么是 E。我们规定 S的价值等于其中包含的子串 BB 以及子串 EE 的数量之和。例如,BBBEEE 中包含 2个 BB 以及 2 个 EE,所以 BBBEEE 的价值等于 4。我们想要计算 S的价值,不幸的是,在我们得到 S之前,约翰将其中的一些字符改为了 F。目前,我们只能看到改动后的字符串 S,对于其中的每个 F,我们并不清楚它之前是 B 还是 E。请你计算,改动前的 S有多少种可能的价值并将所有可能价值全部输出。

输入格式

第一行包含一个整数 N。

第二行包含改动后的字符串 S。

输出格式

第一行输出一个整数 K,表示改动前的 S的可能价值的数量。

接下来 K行,按照升序顺序,每行输出一个可能价值。

数据范围

1≤N≤2×105

思路

1、先分析每一段连续的x的价值有哪些

2、再分析所有段的价值之和有哪些

情况一:全是F FFFFFFFF:0,1,2,3...k-1(F个数为k)

情况二:EFFFFFF:0,1,2,3...k

情况三:EFFFFFE:

        分情况:

                1.F为奇数个:k+1,k-1,k-3...0

                2.F为偶数个:k+1,k-1,k-3...1

情况四:EFFFFFFB:

        1.F为奇数个:k-2,k-4...1

        2.F为偶数个:k-2,k-4...0

为什么情况三和四公差为2?

因为改变一个F两侧价值要么+1要么-1 原价值+奇数+奇数 得到的新价值奇偶性不变

代码

#include
#include
using namespace std;
int n;
string s;
int main()
{
    cin>>n;
    cin>>s;
    //情况1 全部都是F
    if(s == string(n,'F'))
    {
        cout<l&&str[i]==str[i-1])
            {
                low++;
            }
        }
        str = s;
        for(int i=l;i<=r;i++)
        {
            if(str[i]=='F')
            {
                str[i] = str[i-1];
            }
            if(i>l&&str[i]==str[i-1])
            {
                high++;
            }
        }
        int ends = l + n - 1 - r,d = 2;
        if(ends)
        {
            high+=ends,d = 1;
        }
        cout<<(high-low)/d+1<

你可能感兴趣的:(算法)