【cf】D. Backspace

题意:

  给出两个字符串s和t,对于s有两种操作,一种是将s_{i}打印出来,另一种是删除s_{i-1}并且不会打印出s_{i},问能否通过这两个操作得到t

思路:

首先我们可以考虑t已经从s中得到了,但是s还有部分需要打印,那么这部分长度一定是偶数,因为删除操作实际上是删除两个字符(一个是上一次打印出来的,另一个是当前要打印的),如果这部分长度不是偶数个,那么至少会多出一个字符。同样的,t中相邻的两个字符在s中需要间隔偶数个字符,否则也会至少多出一个字符。考虑贪心,从s的末尾往左找满足条件的字符。因为要找的满足条件的最后一个字符的奇偶性是固定的(我们只能从s的末尾开始删除偶数个字符),并且所有t中的字符在s中的位置的奇偶性都是固定的,如果我们不选择离s的末尾最近且等于t的最后一个字符的字符,我们就会找到下一个奇偶性相同且等于t的最后一个字符的位置,选择这两个字符本质上没有区别,而且如果选择离s的末尾更远的字符会将一些可能构成答案的字符略过,所以选择离s的末尾最近且满足条件的方案更优。

代码:

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

int main(){
	int t;
	cin>>t;
	while(t--)
	{
		string s, t;
		cin>>s>>t;
		int i=s.size()-1, j=t.size()-1;
		while(i>=0 && j>=0)
		{
			if(s[i]==t[j]) i--, j--;
			else i-=2;
		}
		if(j==-1) puts("YES");
		else puts("NO");
	}
	
	return 0;
}

[cf] D. Say No to Palindromes

题意:

  一个字符串如果不包含长度至少为2的回文串那么称这个字符串是beautiful的,你可以做的操作是能使一个不beautiful字符串的任意一个字符变为a,b,c中的一个,问给出一个字符串使它变成beautiful所需的最小操作次数。(注意:题目所给的字符串都只由a、b、c三个字符组成)

思路:

  因为不能出现回文串,s_{i}!=s_{i-1} && s_{i}!=s_{i-2} && s_{i-1}!=s_{i-2},并且只有a、b、c三种字符,s_{i}就只能等于s_{i-3}, 所以每三个连续的字符,a、b、c都会出现并且只能出现一次。所以如果第一个和第二个字符确定了那么整个字符就确定了,所以可能的字符串就是由a、b、c的全排列,

也就是abcabc...、acbacb...、bacbac...、bcabca...、cabcab...、cbacba...。因为可能的beautiful字符串就只有这六种,所以可以直接用这六种字符串与给出的字符串比较,找出最小值。

   这里用到了next_permutation函数,是用来求当前全排列的下一个全排列,next_permutation[first, last)如果没有下一个全排列组合就会返回false;否则返回true。

因为最后一个全排列组合会返回false,所以要用do while循环。

代码:

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

int main(){
	int n, m;
	cin>>n>>m;
	string s;
	cin>>s;
	vector<vector<int>> pr(6, vector<int> (n+1));
	string t="abc";
	int cur=0;
	do{
		for(int i=0; i<n; i++)
		{
			pr[cur][i+1]=pr[cur][i]+(s[i]!=t[i%3]);
		}
		cur++;
	}while(next_permutation(t.begin(), t.end()));
	while(m--)
	{
		int l, r;
		cin>>l>>r;
		int ans=n;
		for(int i=0; i<6; i++)
		{
			ans=min(ans, pr[i][r]-pr[i][l-1]);
		}
		cout<<ans<<endl;
	}
	
	return 0;
}

  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值