Codeforces Round 917 (Div. 2)
B. Erase First or Second Letter
题目链接
题意:
给你n和长度为n的小写字母字符串s,可以进行两种操作:
- 删掉第一个字符
- 删掉第二个字符
问通过这两种操作最多可以获得多少种字符串
思路:
不难的好题
很容易想到删掉第二个字符再删第一个字符跟删两次第一次字符是一样的,所以操作可以简化成先删掉x次第一个字符,再删掉y个第二个字符,这样,中间会正好剩下一个字符,加上后面没有删掉字符就构成了一个新字符串。
如果通过不同的操作得到了相同的字符串,那么这两个字符串肯定最前面那个单个字符是一样的,而且后面的部分是一致的。我们通过这两种操作是删不到后面的字符,后面部分一致,只需要后面长度一致即可,为此前面删掉的字符个数就是一样多的,即x+y一样,后面部分就是一样的。
把一个字符串分成两部分,前i个字符选出一个字符,然后通过两种操作把它前后的字符都删掉,再接上后n-i个字符。既然i确定后,后面部分就确定相同了,那么我们考虑前面部分的那一个字符,只要最前面这个字符一致,两个字符串就是一致的,而问有几种不同的字符串,只要枚举前面部分的长度i,统计一下前面部分有几种字符就可以了。
code:
#include <iostream>
#include <cstdio>
#include <set>
#include <cstring>
using namespace std;
typedef long long ll;
int T,n;
string t;
set<char> s;
int main(){
cin>>T;
while(T--){
cin>>n>>t;
s.clear();
ll ans=0;
for(auto &x:t){
if(!s.count(x))
s.insert(x);
ans+=s.size();
}
cout<<ans<<endl;
}
return 0;
}