1020 Delete At Most Two Characters (35 分)(C++)

PAT顶级题解目录​​​​​​​

Given a string which contains only lower case English letters, how many different strings you can get after deleting AT MOST TWO characters in it?

Input Specification:

Each input file contains one test case, which gives the string whose length is in [3,10​6​​].

Output Specification:

Print in a line the number of different strings you can get after deleting at most 2 characters.

Sample Input:

ababcc

Sample Output:

15

Hint:

Deleting 0 character gets ababcc.

Deleting 1 character gets babccaabccabbccabacc and ababc.

Deleting 2 character gets abccbbccbaccbabcaaccaabcabbcabac and abab.

题目大意:给定一个字符串,从中去除0,1,2个字符可以得到多少个不同的字符串?

解题思路:数学问题

假设给定字符串长度为N

去除0个字符串

1种

去除1个字符

若中间无连续的重复字符,应该有N种。但是中间如果存在一段连续的重复字符,长度为 n ,那么需要减去 n-1,有多段的话,同理减去即可

去除2个字符

初始有N*(N-1)/2种

①(X,X,X,X..)长度为n

对于每个单个字符Y而言,去除(X,Y)重复了,需要减去n-1

注意:这里的Y不属于重复子字符串

②(X,X,X,X)长度为m(Y,Y,Y,Y...)长度为n

对于去除(X,Y)的情况,初始计算了(m*n)种,需要减去m*n-1

③X,Y,X

去除(X,Y)和(Y,X)是相同的,减去1

Tips:本题挺容易超时的,能一遍遍历解决的不要遍历两遍,对去除2个字符的第二种情况,在存储了所有的重复子字符串长度后,通过一遍遍历计算得到的是双倍结果,再除以2,用2遍会超时。另外本题用long long int存储结果,否则第三个测试点可能会超时。

代码:

#include <bits/stdc++.h>
using namespace std;
string s;
char c = ' ';
int num = 0;
int main(){
	cin >> s;
	long long int ans = s.length() + 1 + ((s.length()*(s.length()-1)) >> 1), cnt = 0;
	vector<int> v;
	for(int i = 0; i < s.length(); ++ i){
		if(s[i] != c){
			if(num != 0){
				v.push_back(num);
				ans -= (num * (num+1)) >> 1;
				cnt += num;
			}
			num = 0;
			c = s[i];
		}
		else
			++ num;
		if(i+2 < s.length() && s[i] == s[i+2] && s[i] != s[i+1])
			-- ans;
	}
	if(num != 0){
		v.push_back(num);
		ans -= (num * (num+1)) >> 1;
		cnt += num;
	}
	ans += v.size();
	ans -= cnt * (s.length() - cnt - v.size());
	ans -= cnt;
	long long int temp = 0;
	for(long long int i = 0; i < v.size(); ++ i)
			temp += (cnt - v[i] + v.size() - 1) * (v[i]+1);
	printf("%lld\n", ans - temp / 2 + ((v.size()-1) * v.size())/2);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值