坑真的很多,最开始是用两个for嵌套用暴搜然后超时了,改了这种方法,一踩一个坑。

先全部找出C1C2的位置并且记录数量,用C1的位置比对C2的位置,找到C1位置+K-1大于大于C2位置的时候,就把往后的C2字符数量全部加起来,然后跳出C2的循环去下一个C1的位置。这种方法减少了循环次数。

注意:C2没有了之后还可能会有C1,所以全部C2加完后要退出所有循环。

C1C2可能相等,会造成前面搜索C2的时候为0,导致结果为0.

最后输出的子串会很长,光int不够。
参考代码:

#include <stdio.h>

#include <string.h>

char S[5 * 100000 + 1];

int a[500000],b[500000];


int main() {

int K;

scanf("%d", &K);

char c1, c2;

scanf("%s %c %c",&S, &c1, &c2);

getchar();

int len = strlen(S);

long long int t=0;//最后的输出数据会很大,所以一定要+long,不然光int不够最后输出数据会变为负数 

int x=0,y=0;

//找出c1,c2的所在位置以及数量 

for (int i = 0; i < len; i++) {

if (S[i] == c1) {

a[x]=i;

x++;

} else if (S[i] == c2) {

b[y]=i;

y++;

}

//当存在非字母的符号时,使上一个存储的c1位置+1 

else if (S[i] <'a'||S[i]>'z') {

if(i<=a[x-1]+K-1) a[x-1]++;

}

}

int j=0,k;

for(int i=0; i<x; i++) {

//判断c1,c2是否相等,!这是个坑 

if(c1!=c2) {

k=y;

for(; j<k; j++) {

if(a[i]+K-1<=b[j]) {

t=t+y-j;

j--;

k=0;

}

}

if(j==y) break;

} else {

k=x;

for(; j<k; j++) {

if(a[i]+K-1<=a[j]) {

t=t+x-j;

j--;

k=0;

}

}

if(j==x) break;

}

}

printf("%ld\n",t);

return 0;

}


点赞(0)
 

0.0分

0 人评分

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

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

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

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

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

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

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

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

评论列表 共有 0 条评论

暂无评论