解题思路:

对于前缀和,我们用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分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论