Erase First or Second Letter

文章介绍了在一场编程竞赛中的问题,通过删除首尾字符操作,分析如何通过字符计数得出不同字符串种类。主要涉及C++编程实现。
摘要由CSDN通过智能技术生成

Codeforces Round 917 (Div. 2)
B. Erase First or Second Letter
题目链接

题意:

给你n和长度为n的小写字母字符串s,可以进行两种操作:

  1. 删掉第一个字符
  2. 删掉第二个字符

问通过这两种操作最多可以获得多少种字符串

思路:

不难的好题

很容易想到删掉第二个字符再删第一个字符跟删两次第一次字符是一样的,所以操作可以简化成先删掉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;
}
  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`std::vector` 和 `std::list` 都提供了 `erase()` 函数用于删除元素。其函数原型为: ```c++ iterator erase(iterator position); iterator erase(iterator first, iterator last); ``` 其中,`erase(position)` 会删除迭代器 `position` 所指向的元素,并返回指向被删除元素的下一个元素的迭代器;而 `erase(first, last)` 会删除从迭代器 `first` 到迭代器 `last`(不包括 `last`)所指向的所有元素,返回指向被删除元素的下一个元素的迭代器。 下面是 `erase(first, last)` 的简单实现,以 `std::vector` 为例: ```c++ template <typename T> typename std::vector<T>::iterator erase(typename std::vector<T>::iterator first, typename std::vector<T>::iterator last) { auto size = std::distance(first, last); // 计算需要删除的元素个数 auto next = last; // 保存被删除元素的下一个元素的迭代器 while (first != last) { first = vec.erase(first); // 删除元素,并返回下一个元素的迭代器 } return next; } ``` 以上代码中,`std::distance(first, last)` 函数用于计算迭代器 `first` 和迭代器 `last` 之间的距离,即需要删除的元素个数。然后,我们在循环中调用 `vec.erase()` 函数删除元素,并将返回的下一个元素的迭代器保存在 `next` 变量中,最后返回它即可。 需要注意的是,由于 `std::vector` 的 `erase()` 函数可能会使得指向容器其他元素的迭代器、指针和引用失效,因此在循环中我们不能直接使用 `first++`,而要使用 `first = vec.erase(first)` 来更新迭代器 `first`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值