时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
双11又到了,小Z依然只是一只单身狗,对此他是如此的苦恼又无可奈何。
为了在这一天脱单小Z决定向女神表白,但性格腼腆的小Z决定隐晦一点,截取一段包含’L’、’O’、’V’、’E’的英文。(顺序不限)
小Z想起之前小D送给他一本英文书,决定在这里面截取一段话,小Z发现有好多种方案来截取这段话。
你能知道小Z能有多少种方案截取这段话么?
为了简化问题,英文文本讲不会出现空格、换行、标点符号及只有大写的情况。
输入描述:
本题有T组数据。
对于每组数据只有一行文本。
1≤T≤20
1≤文本长度≤100000
输出描述:
输出结果,并换行。
示例1
输入
3
ILOVEACM
LOVELOVE
ALBECVOD
输出
8
15
4
分析:一开始想存一下四个字母出现的位置,然后每次二分查找最近的点进行累加O(nlogn)。
从后向前递推,也可以O(n)通过
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 10;
char str[maxn];
int T;
int main()
{
scanf("%d", &T);
while (T--) {
scanf("%s", str);
long long int ans = 0;
int len = strlen(str);
int L = -1, O = -1, V = -1, E = -1;
for (int i = len - 1; i >= 0; i--) {
if (str[i] == 'L') L = i;
else if (str[i] == 'O') O = i;
else if (str[i] == 'V') V = i;
else if (str[i] == 'E') E = i;
if (L != -1 && V != -1 && O != -1 && E != -1) {
int tmp = max(max(L, E), max(O, V));
ans += 1ll * (len - tmp);
}
}
printf("%lld\n", ans);
}
return 0;
}