LQ0100 人物相关性分析【文本处理】
题目来源:蓝桥杯2019初赛 C++ C组I题
问题描述
小明正在分析一本小说中的人物相关性。他想知道在小说中 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 个字符。
注意:
1.Alice 和 Bob 是大小写敏感的,alice 或 bob 等并不计算在内。
2.Alice 和 Bob 应为单独的单词,前后可以有标点符号和空格,但是不能 有字母。
例如 Bobbi 並不算出现了 Bob。
输入格式
第一行包含一个整数 K。
第二行包含一行字符串,只包含大小写字母、标点符号和空格。长度不超 过 1000000。
对于所有评测用例,1≤ K ≤1000000。
输出格式
输出一个整数,表示 Alice 和 Bob 同时出现的次数。
样例输入
20
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
样例输出
2
问题分析
文本处理问题,不解释。
AC的C语言程序如下:
/* LQ0100 人物相关性分析 */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define N 1000000
char a[N + 1];
int len;
int pos1[N / 5], pos2[N / 3];
int isLetter(int n)
{
if (n < 0 || n >= len) return 0;
return isalpha(a[n]);
}
int main()
{
int k;
fgets(a, N, stdin);
sscanf(a, "%d", &k);
fgets(a, N, stdin);
for (len = 0; a[len] != '\n'; len++);
a[len++] = '\0';
int cnt1 = 0, cnt2 = 0;
for (int i = 0; a[i]; i++) {
if (!isLetter(i - 1) && strncmp(a + i, "Alice", 5) == 0 && !isLetter(i + 5))
pos1[cnt1++] = i, i += 5;
if (!isLetter(i - 1) && strncmp(a + i, "Bob", 3) == 0 && !isLetter(i + 3))
pos2[cnt2++] = i, i += 3;
}
long long ans = 0;
if (cnt1 != 0 && cnt2 != 0) {
int l = 0, r = 0;
for (int i = 0; i < cnt1; i++) {
while (l < cnt2 && pos2[l] < pos1[i] - k - 3)
l++;
while (r < cnt2 && pos2[r] <= pos1[i] + k + 5)
r++;
ans += r - l;
}
}
printf("%lld\n", ans);
return 0;
}