解题思路:
1.直接暴力遍历出c1,c2的位置数组,以及c1,c2的数量。
2.遍历c1,c2数组,用双循环,每一个c1第一次匹配成功c2后边的c2是一定可以匹配这个c1的,时记录该c2的位置,并且下一个c1直接从该位置开始匹配c2.
参考代码:
#include<bits/stdc++.h> using namespace std; #define int long long //这里注意一定要开long long因为字符串长在5*10^5级别!! signed main() { int k; int num=0; char str[500001]; //预留一位存放\0 char start,end; //也就是c1 c2 scanf("%lld %s %c %c",&k,&str,&start,&end); int len=0; //求字符串长 while(str[len]!='\0') { len++; } int startl[len],endl[len]; //存放c1和c2 int l=0; //定义c1和c2的个数 int j=0; for(int i=0;i<len;i++) //填充c1 c2数组 { if(str[i]==start) { startl[j]=i; j++; } if(str[i]==end) { endl[l]=i; l++; } } int oo[len]={0}; //oo数组记录离当前c1最近的c2,即oo[0],下一个c1匹配c2即可直接从oo[0]开始遍历c2 for(int i=0;i<j;i++) { int oi=0; for(int i2=oo[0];i2<l;i2++) { if(endl[i2]-startl[i]+1>=k) //如果子串长度大于等于k即为匹配成功 { oo[oi]=i2; oi++; num+=l-i2; //如果该c2匹配成功则说明后面的c2肯定是子串长大于k的,也一定能匹配上 //所以就不用遍历后边的c2,直接加上去并且break以降低时间复杂度。 break; } } } printf("%lld",num); //注意输出格式为lld; }
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复