Codeforces Round 764 (Div. 3) 补题报告(A~E)

比赛链接

一、概况

比赛名称: Codeforces Round 764 (Div. 3)
日期: 2024.1.31
前两个都是水题,第三个开始没看懂,后来上了课有了思路,虽然错了,但神奇地做对了:)。

二、正解

A. Plus One on the Subset

1 题目描述

有一个长度为 n n n 数列 a a a。定义一次操作如下:

  • a a a 中选出若干个数;
  • 将这些数 + 1 +1 +1,并放回原处。

求至少经过多少次操作后, a a a 数组中所有数一样。

2 大体思路

每次选所有不足最大数的数 + 1 +1 +1 ,不难发现,一共要加的次数就是最小的数要加的次数,即最大值与最小值的差。

3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
ll n,t;
int main(){
	cin>>t;
	while(t--){
		cin>>n;
		ll a[55];
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		sort(a+1,a+1+n);
		cout<<a[n]-a[1]<<endl;
	}
	return 0;
}

B. Make AP

1 题目描述

3 3 3 个整数 a , b , c a,b,c a,b,c 。你需要选择一个整数 m m m ,使 a , b , c a,b,c a,b,c 中的任意一个数乘上它,并让之后的 a , b , c a,b,c a,b,c 构成[等差数列]。如果存在 m m m ,输出YES,否则输出NO

2 大体思路

通过依次改变其中一个数和另外两个不变的数,反推出 m m m ,再验证一下即可。

3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
ll n,t;
int main(){
	cin>>t;
	while(t--){
		ll a,b,c;
		cin>>a>>b>>c;
		if(((2*b-c)>0&&(2*b-c)%a==0)||(a+c)%(b*2)==0||((2*b-a)>0&&(2*b-a)%c==0)){
			printf("YES");
		}
		else{
			printf("NO");
		}
		pr;
	}
	return 0;
}

C. Division by Two and Permutation

1 题目描述

有一个长度为 n n n 的数组 a a a

你可以对其中的数进行以下操作:

  • 不断除以 2 2 2,并向下取整。

求:能否在若干次操作后,使得 a a a 数组变成一个 1 ∼ n 1 \sim n 1n 的全排列。

2 大体思路

输入后,遍历整个序列,并创建一个标记数组。对于每个数,首先将该数反复除,直至处于 1 − N 1-N 1N 范围内且曾经没有出现过(标记数组中该值的下标上的数为0)。若此时该数不为0,则将标记数组中该值的下标上的数标为1。否则,该数无法安放,由于一共要将 n n n 个数全排列,所以此时必定不行。

3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
ll t,n;
bool b[52];
int main(){
	cin>>t;
	while(t--){
		ll n,a[52];
		memset(b,0,sizeof b);
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		bool flag=1;
		for(int i=1;i<=n;i++){
			while(a[i]>n||b[a[i]]==1){
				a[i]/=2;
			}
			if(a[i]==0){
				cout<<"NO";
				flag=0;
				break;
			}
			else{
				b[a[i]]=1;
			}
		}
		if(flag){
			cout<<"YES";
		}
		pr;
	}
	return 0;
}

D. Palindromes Coloring

1 题目描述

将给出的长度为 N N N 字符串划分成 K K K 组,使每组字符串均为回文串,且这 K K K 组字符串中最短的字符串尽可能长。

2 大体思路

输入的串可以分为一个单独的字符和成对的字符,例如字符串 abzhzb 可以分为字符 ha和成对的 bbzz
所以就可以统计字符串中成对的字符的数量和成单的字符的数量,最后计算即可。

3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
ll t,n,k;
ll a[200];
int main(){
	cin>>t;
	while(t--){
		string s;
		cin>>n>>k>>s;
		memset(a,0,sizeof a);
		ll even=0,odd=0;
		for(int i=0;i<s.size();i++){
			a[s[i]]++;
		}
		for(int i='a';i<='z';i++){
			even+=a[i]/2;
			odd+=a[i]%2;
		}
		ll sum=even/k*2;
		odd+=2*(even%k);
		if(odd>=k){
			sum++;
		}
		cout<<sum;pr;
	}
	return 0;
}

E. Masha-forgetful

1 题目描述

给定一个长度为 m m m 的字符串 s s s n n n 个字符串,请问如何用这几个字符串中的各个部分拼出 s s s

2 大体思路

因为题目要求划分出来的字符串长度要大于 1,所以我们选取长度为 2 和 3 的字符串。这时发现,所有长度大于 1的串都能被若干长度为 2和 3的子串划分,这意味着我们只需插入与查询长度为 2和 3的字符串了.。

3 AC代码

#include<bits/stdc++.h>
#define ll long long
#define bug printf("---OK---")
#define pa printf("A: ")
#define pr printf("\n")
#define pi acos(-1.0)
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
ll t,n,m,pre[1010],lst[1010];
char c[1010];
bool ck[1010];
struct node{
	ll l,r,id;
}f2[99],f3[999],f[1010];
int main(){
	scanf("%lld",&t);
	while(t--){
		scanf("%lld %lld",&n,&m);
		for(ll i=1;i<=n;i++){
			scanf("%s",c+1);
			for(ll j=1;j<=m-1;j++){
				ll tmp=(c[j]-'0')*10+(c[j+1]-'0');
				f2[tmp]=(node){j,j+1,i};
			}
			for(ll j=1;j<=m-2;j++){
				ll tmp=(c[j]-'0')*100+(c[j+1]-'0')*10+(c[j+2]-'0');
				f3[tmp]=(node){j,j+2,i};
			}
		}
		scanf("%s",c+1);
		ck[0]=1;
		for(ll i=1;i<=m;i++){
			ll tmp;
			if(i>1){
				tmp=(c[i-1]-'0')*10+(c[i]-'0');
				if(f2[tmp].id){
					if(ck[i-2]){
						ck[i]=1;
						lst[i]=i-2;
						f[i]=f2[tmp];
					}
				}
			}
			if(i>2){
				tmp=(c[i-2]-'0')*100+(c[i-1]-'0')*10+(c[i]-'0');
				if(f3[tmp].id){
					if(ck[i-3]){
						ck[i]=1;
						lst[i]=i-3;
						f[i]=f3[tmp];
					}
				}
			}
		}
		if(!ck[m]) printf("-1\n");
		else{
			ll ans=0;
			for(ll i=m;i;i=lst[i],ans++) pre[lst[i]]=i;
			printf("%lld\n",ans);
			for(ll i=pre[0];i;i=pre[i]) printf("%lld %lld %lld\n",f[i].l,f[i].r,f[i].id);
		}
		for(ll i=0;i<=99;i++){
			f2[i]=(node){0,0,0};
		}
		for(ll i=0;i<=999;i++){
			f3[i]=(node){0,0,0};
		}
		for(ll i=1;i<=m;i++){
			f[i]=(node){0,0,0};
		}
		for(ll i=1;i<=m;i++){
			ck[i]=0;
		}
		for(ll i=0;i<=m;i++){
			lst[i]=pre[i]=0;
		}
	}
}
  • 47
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
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 ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值