题目描述
咕咕东很聪明,但他最近不幸被来自宇宙的宇宙射线击中,遭到了降智打击,他的英语水平被归 零了!这一切的始作俑者宇宙狗却毫不知情! 此时咕咕东碰到了一个好心人——TT,TT在吸猫之余教咕咕东学英语。今天TT打算教咕咕东字母A 和字母B,TT给了咕咕东一个只有大写A、B组成的序列,让咕咕东分辨这些字母。 但是咕咕东的其他学科水平都还在,敏锐的咕咕东想出一个问题考考TT:咕咕东问TT这个字符串 有多少个子串是Delicious的。 TT虽然会做这个问题,但是他吸完猫发现辉夜大小姐更新了,不想回答这个问题,并抛给了你, 你能帮他解决这个问题吗? Delicious定义:对于一个字符串,我们认为它是Delicious的当且仅当它的每一个字符都属于一个 大于1的回文子串中。
输入描述
输入第一行一个正整数n,表示字符串长度 接下来一行,一个长度为n只由大写字母A、B构成的字符串。
输出描述
输出仅一行,表示符合题目要求的子串的个数。
样例输入
5
AABBB
样例输出
6
样例解释
对于该样例,符合条件的六个子串分别是:
数据组成
思路
C 题正解
仔细思考以后,可以发现正着做这题很麻烦,也不知道咋做
因此正难则反,答案 = 所有子串 – 不合法串
不合法串
稍微多画几个例子,可以发现不合法的串只有以下 4 种情况
考察思维能力
ABB…BB
BAA…AA
AA…AAB
BB…BBA
因此分类枚举所有不合法情况即可拿到所有分数
不合法串
[ABB…BB, BAA…AA, AA…AAB, BB…BBA]
识别出连续的一段,判断左右是否有字符即可
小细节注意: AB 会算两次,因此算贡献时要仔细考虑
PS:T1 也是识别连续的一段
代码
#include<iostream>
using namespace std;
const int maxn=3e5+10;
char c[maxn];
int main()
{
int n;
cin>>n;
cin>>c;
long long ans=(long long)n*(n-1)/2;
int i=0;
int l=0;
int r=0;
while(c[i]==c[0])
{
l++;
i++;
}
ans-=(n-l);
int now=c[0];
for(i;i<n;i++)
{
if(c[i]!=now)
{
ans++;
now=c[i];
}
}
i=n-1;
while(c[i]==c[n-1])
{
i--;
r++;
}
ans-=(n-r);
// cout<<l<<' '<<ans<<' '<<r<<endl;
cout<<ans<<endl;
return 0;
}