Codeforces 855 div3 A-F

A. Is It a Cat?

分析

模拟题,关键就是看代码怎么写好写

可以先把所有的大写字母变成小写,这样判断时方便一点

string t='m';

然后从第二个字符往后遍历,每次遇到与前一个字符不同的字符,将该字符加入到字符串 t 中,最后看t是否等于meow

C++代码

#include<iostream>
using namespace std;
const int N=200010;
void solve(){
	int n;
	string s;
   	cin>>n>>s;
    for(int i=0;i<n;i++)
        if(s[i]>='A'&&s[i]<='Z')
            s[i]=s[i]+32;//全变成小写 

    string t;
    t+=s[0];
    for(int i=1;i<s.size();i++)
        if(s[i]!=s[i-1])
            t+=s[i];

    if(t=="meow")puts("Yes");
    else puts("No");
}
int main(){
    int t;
    cin>>t;
    while(t--){
    	solve();
    }
    return 0;
}

B. Count the Number of Pairs

分析

找到每个字母的大小写的个数,二者取min就是不改变任何字母对答案的贡献,所有字母最初贡献和用sum记录

cnt记录匹配完后剩下的字母最多对答案的贡献

每个字母匹配完后只会剩下纯大写或纯小写字母,这样对答案的贡献就是字母数量的一半

依次处理每个字母即可

然后判断k和cnt的大小,答案为sum+min(k,cnt)

C++代码

#include<iostream>
using namespace std;
void solve(){
	int n,k;
	cin>>n>>k;
	string s;
	cin>>s;
	int a[26]={0},b[26]={0};//分别存储大小写字母的个数
	for(int i=0;i<s.size();i++){
		if(s[i]>='a'&&s[i]<='z')a[s[i]-'a']++;
		else if(s[i]>='A'&&s[i]<='Z')b[s[i]-'A']++;
	}
	int sum=0,cnt=0;
	for(int i=0;i<26;i++){
		sum+=min(a[i],b[i]);//不变字母就可以找到的大小写字母对数
		cnt+=abs(a[i]-b[i])/2;//改变第i个字母最多对答案的贡献
	}
    //一共只能操作k次,就看cnt和k哪个更小
	sum+=min(cnt,k);
	cout<<sum<<endl;
}
int main(){
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

C1&C2. Powering the Hero

分析

使用大根堆,从前往后遍历每个数,sum记录答案

遇到0,sum加上堆顶元素,然后堆顶元素出队

遇到非0就将该元素入堆

C++代码

#include<iostream>
#include<queue>
using namespace std;
typedef long long LL;
const int N=5010;
int a[N];
void solve(){
	LL n,sum=0;
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	priority_queue<int> q;
	for(int i=1;i<=n;i++){
		if(a[i]==0&&q.size()){
			sum+=q.top();
			q.pop();
		}else{
			q.push(a[i]);
		}
	}
	cout<<sum<<endl;
}
int main(){
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

D. Remove Two Letters

分析

因为每次只能删两个相邻元素,所以对于每个元素,会出现在两个删除的序列中

a[i]所在的删除序列就是a[i-1]和a[i],a[i]和a[i+1]这两个

可以发现,如果a[i-1]==a[i+1],则删除这两个序列后形成的新字符串是相同的,所以我们只需要记录一次就好

每次删两个字符,故删除的情况有n-1种,可以形成n-1个新的字符串,答案ans最初为n-1,但是每次遇到s[i-1]==s[i+1]时,我们就要将ans--

C++代码

#include<iostream>
using namespace std;
void solve(){
	int n,ans;
	string s;
	cin>>n>>s;
	ans=n-1;
	for(int i=1;i<s.size();i++){
		if(s[i-1]==s[i+1])ans--;
	}
	cout<<ans<<'\n';
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

E1&E2. Unforgivable Curse

分析

i可以和i+ki+k+1交换

i+1可以和i+k+1i+k+2

所以i可以和i+1换,一次类推,i,i+1,i+2,... 都是可以互换的,如果所有s[i]和t[i]不同的字符都可以互换,则一定可以将s变成t

所以我们要找到存在s[i]!=t[i]的字符不可以互换的情况

不难发现,只要 i 前面有字符可以到他或者 i 可以到他后面的字符,则i一定可以与其他的字符连通,所以不连通的情况就是i<k&&i+k>=n(字符串编号从0开始)

在找之前需要判断s和t中所含的字母是否相同,如果不同则直接输出NO;否则就进行如上判断

C++代码

#include<iostream>
using namespace std;
void solve(){
	int n,k;
	cin>>n>>k;
	string s,t;
	cin>>s>>t;
	int a[26]={0},b[26]={0};
	for(int i=0;i<n;i++)a[s[i]-'a']++,b[t[i]-'a']++;
	for(int i=0;i<26;i++)
		if(a[i]!=b[i]){
			cout<<"NO"<<'\n';
			return;
		}
	for(int i=0;i<n;i++)
		if(s[i]!=t[i]&&i<k&&i+k>=n){
			cout<<"NO"<<'\n';
			return;
		}
	cout<<"YES"<<'\n';
}
int main(){
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

F. Dasha and Nightmares

分析

S=s[i]+s[j]有三个条件

1、一共有奇数个字母

2、s[i]中一共有25个英文字母

3、每个英文字母出现的次数都是奇数个

会发现25个奇数相加还是奇数,所以只需要考虑条件2和3即可

记录每个字符串的状态,由于只有26个英文字母,二进制状态一定小于2^26,在int范围内,所以只需要开两个数组a和b

a[i]记录第i个字符串每个字符是否出现

b[i]记录第i个字符串每个字符的个数是否为奇数,如果是二进制对应位就是1,否则是0

一共25个字符,所以枚举那个不存在的字符(假设编号为i),然后枚举所有不存在该字符的字符串,找到该字符串对应的状态b[j],两个字符串合体成为一个字符串时,它们的状态b直接异或就是新的字符串的状态了,因为只有奇+偶=奇,其余全是偶数

C++代码

#include<iostream>
using namespace std;
typedef long long LL;
const int N=200010;
int a[N],b[N],cnt[1<<26];
string s;
int n;
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>s;
        //初始化a[i]和b[i]
		for(int j=0;j<s.size();j++)
			a[i]|=(1<<(s[j]-'a')),b[i]^=(1<<(s[j]-'a'));
	}
	LL ans=0;
	for(int i=0;i<26;i++){//枚举每个字母不在的情况,0~25表示a~z 
		int t=(1<<26)-1-(1<<i);//一共25个字母,i+'a'不存在的情况 
		for(int j=1;j<=n;j++){//枚举n个字符串 
			if(!(a[j]>>i&1)){//第i个字母必须不存在 
				cnt[b[j]]++;
				ans+=cnt[b[j]^t];
			}
		}
        //清空cnt数组
		for(int j=1;j<=n;j++)
			if(!(a[j]>>i&1))cnt[b[j]]--;
	}
	cout<<ans<<endl;
}
int main(){
	solve();
	return 0;
}

  • 17
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值