解题思路:
对于前缀和,我们用L和R表示字符串的左端点和右端点;我们用一个前缀和数组s[N]来维护a出现的次数,表示在第i位之前有多少个a。处理完后直接将字符串从后往前枚举,如果找到一个b,则可以匹配前面s[i-k+1]个a;把这些数累加起来即可解题
对于双指针,我们可以定义一个区间,这个区间的大小为k,左端点为j,右端点为i,然后枚举字符串,首先判断下标为j的字符是否是我们需要匹配的字符a,是的话我们把它累加到cnt里面去,在判断右端点i是否为我们需要匹配的字符b,如果是的话,则说明b前面我们可以匹配上cnt个a,所以我们把它累加起来。最后输出答案即可
注意事项:
最后的数可能有点大,我也不会算,直接用longlong保证
参考代码:
前缀和
#include
using namespace std;
const int N = 500010;
char g[N],a,b;
int s[N]; //前缀和
int n,k;
int main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>k>>g+1>>a>>b;
n = strlen(g+1);
//预处理前缀和
for(int i = 1;i<=n;i++)
if(g[i] == a)
s[i] = s[i-1]+1;
else
s[i] = s[i-1];
long long ans = 0;
//枚举字符串
for(int i = n;i>=k;i--)
if(g[i] == b)
ans+=s[i - k + 1];
cout<<ans<<endl;
return 0;
}
双指针
#include
using namespace std;
const int N = 500010;
char g[N],a,b;
int n,k;
int main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>k>>g+1>>a>>b;
n = strlen(g+1);
int cnt = 0;
long long ans = 0;
//枚举字符串
for(int i = k,j =1;i<=n;i++,j++){
if(g[j] == a) cnt++;
if(g[i] == b) ans+=cnt;
}
cout<<ans<<endl;
return 0;
}
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复