题目描述
小明正在分析一本小说中的人物相关性。
他想知道在小说中 Alice
和 Bob
有多少次同时出现。
更准确的说,小明定义 Alice
和 Bob
“同时出现”的意思是:在小说文本中 Alice
和 Bob
之间不超过 K
个字符。
例如以下文本:
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
假设 K = 20,则 Alice
和 Bob
同时出现了 2 次,分别是 Alice and Bob
和 Bob. Alice
。
前者 Alice
和 Bob
之间有 5 个字符,后者有 2 个字符。
注意:
Alice
和Bob
是大小写敏感的,alice
或bob
等并不计算在内。Alice
和Bob
应为单独的单词,前后可以有标点符号和空格,但是不能有字母。例如 Bobbi 並不算出现了Bob
。
输入格式
第一行包含一个整数 K。
第二行包含一行字符串,只包含大小写字母、标点符号和空格,长度不超过 1000000。
输出格式
输出一个整数,表示 Alice 和 Bob 同时出现的次数。
数据范围
1 ≤ K ≤ 106
输入样例
20
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
输出样例
2
题解
双指针:
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
using namespace std;
vector<int> Alice, Bob;
bool check(char c)
{
return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
}
int main()
{
int k;
cin >> k;
getchar();
string s;
getline(cin, s);
for (int i = 0; i < s.size(); i ++)
{
if(s[i] == 'A')
{
if(s.substr(i, 5) == "Alice")
if((i - 1 == -1 || !check(s[i - 1])) && (i + 5 == s.size() || !check(s[i + 5])))
Alice.push_back(i);
}
else if(s[i] == 'B')
{
if(s.substr(i, 3) == "Bob")
if((i - 1 == -1 || !check(s[i - 1])) && (i + 3 == s.size() || !check(s[i + 3])))
Bob.push_back(i);
}
}
long long ans = 0;
for (int i = 0, L = 0, R = 0; i < Alice.size(); i ++) // 统计 Alice 前面 Bob 出现了几次
{
while(R < Bob.size() && Alice[i] > Bob[R]) R ++;
while(L < R && Alice[i] - Bob[L] > k + 3) L ++;
ans += R - L;
}
for (int i = 0, L = 0, R = 0; i < Bob.size(); i ++) // 统计 Bob 前面 Alice 出现了几次
{
while(R < Alice.size() && Bob[i] > Alice[R]) R ++;
while(L < R && Bob[i] - Alice[L] > k + 5) L ++;
ans += R - L;
}
cout << ans << endl;
return 0;
}