解题思路:

主要思想是滑动窗口

用两个数组记录Alice和Bob出现时(首字母)的下标

遍历Alice数组中的元素,在Bob数组中维护范围内的窗口

范围为:Alice[i] - k - 3 <= Bob[ ] <= Alice[i] + k + 5   (3 和 5 分别为Bob和Alice的长度)

每次循环让答案加上窗口长度即可(我代码中的 br 表示的是窗口右边界后一位,是为方便计算)

细节请看代码

参考代码:

#include <bits/stdc++.h>
using namespace std;

string s;			//定义全局变量s 

bool checkA(int i, int len){		//判断是否为Alice, i为下标, len为字符串长度 
    if(len - i < 5)	return false;
    return s[i+1] == 'l' && s[i+2] == 'i' && s[i+3] == 'c' && s[i+4] == 'e';
}

bool checkB(int i, int len){			//判断是否为Bob, i为下标, len为字符串长度 
    if(len - i < 3)	return false;
    return s[i+1] == 'o' && s[i+2] == 'b';
}

int main(){
    int k;			//定义k 
    cin >> k;		//输入k 
    getchar();		//吃回车 
    
    getline(cin, s);		//整行输入字符串s 
    int len = s.length();	//定义len为s的长度 

    vector<int> Alice, Bob;		//定义数组记录名字出现时的下标 

    for(int i = 0; i < len; i++){			//遍历字符串 
        if(s[i] == 'A' && checkA(i, len)){	//如果字符为'A'判断是否为Alice 
            Alice.push_back(i);				//添加下标到数组 
            i += 5;				//跳过名字(名字后后空格,无需担心循环中的i++)
        }
        else if(s[i] == 'B' && checkB(i, len)){	//如果字符为'B'判断是否为Bob 
            Bob.push_back(i);					//添加下标到数组 
            i += 3;				//跳过名字
        }
    }

    int As = Alice.size(), Bs = Bob.size();		//As与Bs分别为两数组元素个数 
    int bl = 0, br = 0;			//bl与br分别为窗口左右边界 
    
    long long ans = 0;			//定义答案(最后一个评测点会超过int范围) 
    
    for(int i = 0; i < As; i++){	//遍历Alice数组元素 
    	while(bl < Bs && Bob[bl] < Alice[i] - k - 3)	bl++;	//维护窗口左边界 
    	while(br < Bs && Bob[br] <= Alice[i] + k + 5)	br++;	//维护窗口右边界 
    	ans += br - bl;				//答案加上窗口中元素个数 
	}
	
	cout << ans << endl;		//输出答案 
    return 0;
}


点赞(0)
 

0.0分

11 人评分

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

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

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

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

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

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

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

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

评论列表 共有 3 条评论

ccccc 3年前 回复TA
while(bl < Bs && Bob[bl] < Alice[i] - k - 3)    bl++;   //维护窗口左边界 
        while(br < Bs && Bob[br] <= Alice[i] + k + 5)   br++;   //维护窗口右边界 


这段没看懂
CodeRookie 3年前 回复TA
@LunDon 确实,多谢指教!如果要严谨的话,要再确保后面没有多跟了字母或数字,可以在 checkA 函数里加上 && ( ! isalnum(s[i + 5]) ) ,同样的在 checkB 函数里加上 && ( ! isalnum(s[i + 3]) )
LunDon 3年前 回复TA
有一个问题,这样子输入
20
This is a story about Alice and Bob. Alicee wants to send a private message to Bob
依然是输出2,可是是Alicee,没有判断Alice或者Bob这个单词是否是独立的?