G. ABBC or BACB

G. ABBC or BACB

You are given a string s made up of characters A and B. Initially you have no coins. You can perform two types of operations:

  • Pick a substring AB, change it to BC, and get a coin.
  • Pick a substring BA, change it to CB, and get a coin.

What is the most number of coins you can obtain?
A substring of length 2 is a sequence of two adjacent characters of a string.

Input

The input consists of multiple test cases. The first line of the input contains a single integer t (1t1000) — the number of test cases.

The only line of each test case contains the string s (1|s|2105). All characters of s are either A or B.

The sum of the lengths of s over all test cases does not exceed 2105.

Output

For each test case, output a single integer — the maximum number of coins you can obtain.

Example

input

8
ABBA
ABA
BAABA
ABB
AAAAAAB
BABA
B
AAA

output

2
1
3
1
6
2
0
0

Note

In the first test case you can perform the following operations to get 2 coins: ABBABCBABCCB

In the second test case you can perform the following operation to get 1 coin: ABABCA

In the third test case you can perform the following operations to get 3 coins: BAABACBABACBACBCCBCB

 

解题思路

  经典思维题不会做.jpg

  官方给出的题解很长,这里简练下给出其核心思想。最关键的地方是要注意到任意一种操作执行后字符 B 的变化情况。

  如果是 ABBC,那么可以理解成 B 左移并覆盖其左邻的 A,再用 C 覆盖原来的位置。同理对于 BACB,可以理解成 B 右移并覆盖其右邻的 A,再用 C 覆盖原来的位置。

  因此对于 AAAB 这一类字符串,将 B 不断左移并覆盖,即有 AAABAABCABCCBCCC,那么就可以获得最大收益(即操作次数最多)。同理对于 BAAA 这一类字符串,将 B 不断右移并覆盖,即有 BAAACBAACCBACCCB,可以获得最大收益。

  因此可以发现对于一个字符 B,如果其两边相邻的都是 A,那么可以选择左移或右移,并且之后只能向同个方向移动(因为另一个方向会变成 C)。因此一个字符 B 只能覆盖某一段与其相邻且连续的 A。所以我们找到字符串中所有的 B,假设有 k 个,那么就会将整个字符串中的 A 分成 k+1 个段(包括空串)。例如有 AABBAAAB,那么 A 就被分成 {AA,ϕ,AAA,ϕ}。由于 kB 只能覆盖 k 段的 A,意味着必然有一段 A 无法被覆盖,而为了得到最大收益,我们选择长度最小的那段舍弃即可。

  因此我们只需根据 B 的划分来累加每一段 A 的长度,并维护长度的最小值。最后答案就是 A 的个数减去这个最小值。

  AC 代码如下,时间复杂度为 O(n)

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 2e5 + 10;

char s[N];

void solve() {
	scanf("%s", s);
	int sum = 0, mn = 1e9;
	for (int i = 0, j = -1; s[i]; i++) {
		if (s[i] == 'B') {
			int t = i - j - 1;
			sum += t;
			mn = min(mn, t);
			j = i;
		}
		if (!s[i + 1]) {
			int t = i - j;
			sum += t;
			mn = min(mn, t);
		}
	}
	printf("%d\n", sum - mn);
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		solve();
	}
	
	return 0;
}

 

参考资料

  Codeforces Round #898 (Div. 4) Editorial:https://codeforces.com/blog/entry/120634

  Codeforces Round 898 (Div. 4)A-H:https://zhuanlan.zhihu.com/p/657711661

posted @   onlyblues  阅读(68)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示