Codeforces Round #849 (Div. 4)--D. Distinct Split

Let's denote the f(x) function for a string x as the number of distinct characters that the string contains. For example f(abc)=3, f(bbbbb)=1, and f(babacaba)=3.

Given a string s, split it into two non-empty strings a and b such that f(a)+f(b) is the maximum possible. In other words, find the maximum possible value of f(a)+f(b) such that a+b=s (the concatenation of string a and string b is equal to string s).

Input

The input consists of multiple test cases. The first line contains an integer t (1≤t≤10^4) — the number of test cases. The description of the test cases follows.

The first line of each test case contains an integer n (2≤n≤2⋅10^5) — the length of the string s.

The second line contains the string s, consisting of lowercase English letters.

It is guaranteed that the sum of nn over all test cases does not exceed 2⋅10^5.

Output

For each test case, output a single integer  — the maximum possible value of f(a)+f(b) such that a+b=s.

输入:

5
2
aa
7
abcabcd
5
aaaaa
10
paiumoment
4
aazz

输出:

2
7
2
10
3

Note

For the first test case, there is only one valid way to split aa into two non-empty strings a and a, and f(a)+f(a)=1+1=2.

For the second test case, by splitting abcabcd into abc and abcd we can get the answer of f(abc)+f(abcd)=3+4=7 which is maximum possible.

For the third test case, it doesn't matter how we split the string, the answer will always be 2.

题意:将串s切一刀分成两个子串,使得两个串各出现不同字母数和最大。

初始:刚开始想到遇到第一个重复的字母直接切,但后面考虑不合理比如abcdaefgefg最多可以为10,如果按照刚才想法就错了

解析:最终分为左右串,我们可以先看作全部是右串,然后算出cnt(出现不同字母数量),同时记录在r[ ]中,然后遍历枚举如果切1~n-1,那么L[ s[i]-'a']++,表示进入左串,如果L[ s[i]-'a' ]=1,那么就是左边加入新出现字母,cnt++,同时我们要判读是否右串中R[ s[i]-'a' ]是否为0,如果为0的话,那么cnt--,如此每次更新ans最大数量即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=30;
int l[N],r[N];
void solve()
{
	memset(l,0,sizeof l);//多组清空
	memset(r,0,sizeof r);
	int n;
	string a;
	scanf("%d",&n);
	cin>>a;
	for(int i=0;i<n;i++) r[a[i]-'a']++;
	int cnt=0;
	for(int i=0;i<26;i++)//统计出现不同字母数量
	{
		if(r[i]>0) cnt++;
	}
	int ans=0;
	for(int i=0;i<n-1;i++)
	{
		int k=a[i]-'a';
		l[k]++;
		r[k]--;
		if(r[k]==0) cnt--;//表示右串这个字母没了
		if(l[k]==1) cnt++;
		ans=max(ans,cnt);//更新ans
	}
	printf("%d\n",ans);
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--) solve();
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值