题意:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200507170320756.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhbnppeGlhbmc=,size_16,color_FFFFFF,t_70)
输入:
输入第一行一个正整数n,表示字符串长度 接下来一行,一个长度为n只由大写字母A、B构成的字符串。
输出:
输出仅一行,表示符合题目要求的子串的个数。
样例:
输入:
5
AABBB
输出:
6
思路:
主要是设个delicious的定义很难理解,当时看了很长时间,然后也没什么思路。想着用暴力来打几个分数。但后来补题的时候发现对delicious的理解还是有错。一开始暴力打的时候想着从正面,即对每个字串进行判断。但肯定是不能过的。所以得去反面考虑,注意:这个字符串是只有A和B。这是一个很重要的条件,然后从这个条件出发,因为字符串要大于等于2。最基础的有AB,和BA的字符串不是delicious。从这两个字符串出发,发现,
从AB出发:AAB,AAAB,AAAAB,A……AAAB。 ABB,ABBB,ABBBB,ABBB……BB。发现分别从左侧加A和从右侧加B的都不是delicious。
从BA出发:BBA,BBBA,BBB……BA。 BAA,BAAA,BAAAA,BAA……AAA都不是delicious。与上一个一样。
故对AAAAB,和BBBBBA的类型,可以从左侧往右侧遍历。即遇到字母不同的就计算个数。如:AAAAB中包含AAAB,AAB,AB。
对ABBBBB,和BAAAAAA的类型,可以从右往左遍历,即遇到字母不同的,计算个数。但注意,和从左往右的一样,其中也记录了一次AB,或者是BA,即于上面的多减了一次。需要加回去。
然后总的字符串数量易知是N*(N-1)/2。然后减去不是delicious的字符串的数量即可。
总结:
首先一定要弄懂delicious的含义,其次一定要抓住只有AB两种字符。后来请教了一下同学得时候,发现delicious得含义还是弄错了。然后觉得可能是一个很难得算法,得写很多的那种。当然这个思路如果没有一个启发的话,一直钻牛角的话还是很难转变想到这个的。然后就是注意数据范围,最终的结果int是会爆炸的。
代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
string a;
long long N;
long long num=0;
long long last;
int main() {
ios::sync_with_stdio(0);
cin >> N;
cin >> a;
num=N*(N-1)/2;
last=0;
for(int i=1;i<N;i++){
if(a[i]!=a[i-1]){
num-=(i-last);
last=i;
num++;
}
}
last=N-1;
for(int i=N-2;i>=0;i--){
if(a[i]!=a[i+1]){
num-=(last-i);
last=i;
}
}
cout<<num<<endl;
return 0;
}