CF412E 题解

思路

首先找出每个相邻的 @. 的位置,然后判断 @. 之间是否合法,若合法,枚举 @ 前的连续的仅由小写字母、数字和下划线构成的最长子串,并数出其中的小写字母的个数 s1s1 作为开头,再枚举 . 后面的仅由小写字母构成的最长子串,并数出其中的小写字母个数 s2s2 作为结尾,然后根据乘法原理,这一对 @. 能构成的“电子邮箱”就是 s1×s2s1\times s2。此外,@. 之间没有任何字符的情况需要特判。

代码

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
string a;
int n, at = -1, l, r;
vector <pii> v;
ll sum;
int main () {
	ios::sync_with_stdio (0);
	cin.tie (0);
	cout.tie (0);
	cin >> a;
	n = a.size ();
	for (int i = 0; i < n; ++ i)
		if (a[i] == '@')
			at = i;
		else if (a[i] == '.' && ~ at)
			v.push_back ({at, i}), at = -1;
	for (pii &i : v) {
		if (i.first + 1 >= i.second)
			continue ;
		for (int j = i.first + 1; j < i.second; ++ j)
			if (a[j] == '_')
				goto end;
		l = r = 0;
		for (int j = i.first - 1; ~j; -- j)
			if (a[j] == '.' || a[j] == '@')
				break ;
			else if (a[j] >= 'a' && a[j] <= 'z')
				++ l;
		for (int j = i.second + 1; j < n; ++ j)
			if (a[j] < 'a' || a[j] > 'z')
				break ;
			else
				++ r;
		sum += (ll) l * r;
end:
		;
	}
	cout << sum;
	return 0;
}
posted @ 2024-03-29 10:16  Vitamin_B  阅读(7)  评论(0)    收藏  举报  来源