题目:
第八题:人物相关性分析
题目描述
小明正在分析一本小说中的人物相关性。他想知道在小说中 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 同时出现的次数。
【样例输入】
20
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
【样例输出】
2
分别在左右设置l,r作为标记点,
遍历一次字符串记录下Alice和Bob出现的下标,然后从Alice第一次出现的位置开始搜索,对于l,要找到Bob的位置第一次距离Alice小于k的位置,然后记录;对于r,找到Bob的位置第一次距离Alice大于k的位置。注意我把Alice和Bob的下标存在vector里面,所以Alice[l]中l表示的是第几个Alice,而Alice[l]表示的是Alice第l次出现在字符串中的下标。所以在这个Alice中,与它同时出现的Bob个数是r - l;之后再找下一个Alice,r和l还是从上次的开始搜索,因为这个Alice肯定下标比上一个大,那么左边的Bob与上一个的差距大于k的,肯定与这个也大于k,所以就不用再判断了,接着上一次左边的位置向右判断就行,右边也是同理,右边的Bob与上一个的差距小于k的,肯定与这个也小于k,所以接着上一次右边的位置向右判断就行。
import java.util.Scanner;
import java.util.Vector;
public class okt8人物相关性分析 {
public static void main(String[] args) {
f2();
}
private static void f2() {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
int k = scanner.nextInt();
scanner.nextLine();
String string = scanner.nextLine();
Vector<Integer> A = new Vector<Integer>();
Vector<Integer> B = new Vector<Integer>();
for (int i = 0; i < string.length(); i++) {
if (string.charAt(i) == 'A') {
if (string.substring(i, i + 6).equals("Alice ") || string.substring(i, i + 6).equals("Alice.")) {
A.add(i);
// System.out.println(i + string.substring(i, i + 6));
i += 5;
}
}
if (string.charAt(i) == 'B') {
if (string.substring(i, i + 3).equals("Bob ") || string.substring(i, i + 4).equals("Bob.")) {
B.add(i);
// System.out.println(i);
i += 3;
}
}
}
int l = 0;
int r = 0;
long ans = 0;
for (int i = 0; i < A.size(); i++) {
// System.out.println(A.get(i));
// System.out.println(B.get(i));
while (l < B.size() && B.get(l) < A.get(i) - k - 3)
l++;
while (r < B.size() && B.get(r) <= A.get(i) + k + 5)
r++;
ans += r - l;
// System.out.println(l + " " + r);
}
System.out.println(ans);
}
}