题面:
给定一个只含大写AB的字符串,问这个字符串有多少个子串是Delicious的。
Delicious定义:对于一个字符串,我们认为它是Delicious的当且仅当它的每一个字符都属于一个大于1的回文子串中
输入第一行一个正整数n,表示字符串长度,接下来一行,一个长度为n只由大写字母A、B构成的字符串
输出仅一行,表示符合题目要求的子串的个数。
sample input:
5
AABBB
sample output:
6
(对于该样例,符合条件的六个子串分别是:s1-s2,s1-s4,s1-s5,s3-s4,s3-s5,s4-s5)
数据组成
思路:
- 测试的时候完全没有懂这个题目在说什么,所以最后随缘写了一个混了一个样例分,当时的思路是先把所有回文子串找出来再想办法算总数,然后就绕进去了
- 首先要理解他的样例的意思,要求所有字符都属于长度大于一并且完整包含在字符串的回文子串中,也就是说如果出现了单个的与上个字符不相同的字符就肯定是错的,比如AAB,AAAB
- 首先利用公式计算出字符串所有子串的个数ans,然后对于不符合条件的子串进行计数。利用pos记录上一次AB\BA的分界处,利用num记录AB\BA个数。从头到尾再从尾到头遍历,寻找交界位置,即不符合条件的子串。
- 需要注意的是从头到尾从尾到头的两次是为了防止ABBB,AAAB情况的遗漏,但是这样就减了两次AB\BA,所以加上一个num
- 由于n到达了五次方,所以使用long long 定义ans
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
long long n;
long long ans=0;
scanf("%d",&n);
string s;
cin>>s;
int pos=0;
int num=0;
int loss=0;
ans=(n*(n-1))/2;
for(int i=0;i<n-1;i++)
{
if(s[i]!=s[i+1])
{
loss+=(i+1-pos);
pos=i+1;
num++;
}
}
pos=n-1;
for(int i=n-1;i>0;i--)
{
if(s[i]!=s[i-1])
{
loss+=(pos-i+1);
pos=i-1;
}
}
ans=ans-loss+num;
printf("%lld",ans);
return 0;
}