CF1624补题报告

文章介绍了五道编程比赛题目,涉及加一操作、构造等差数列、除以2变成全排列、涂色构造回文串和小可记数字的处理,展示了作者对算法和数据结构的运用。
摘要由CSDN通过智能技术生成

比赛

时间:2024.2.1

链接:Dashboard - Codeforces Round 764 (Div. 3) - Codeforces

 题目

一、Plus One on the Subset(子集全加一)

题目描述

输入n个数字的序列,每次操作可以将任意几个数加1,求最少几次可以把整个序列变为全部相等。

思路

因为要次数最少,所以最大的应该不动,次数就为最小值加到最大值的次数。

AC代码
#include<bits/stdc++.h>
#define TIE ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define inf 0x3f3f3f3f
using namespace std;
int t,n,a,mx,mn;
signed main(){
	TIE;cin>>t;
	while(t--){
		cin>>n;mx=0;mn=inf;
		for(int i=1;i<=n;i++){cin>>a;mx=max(mx,a);mn=min(mn,a);}
		cout<<mx-mn<<'\n';
	}
	return 0;
} 

二、Make AP(构造等差数列)

题目描述

给定三个整数a,b,c,进行一次操作,可以给abc任意一个×正整数m,若能构造成等差数列输出yes,否则输出no

思路

枚举三种情况,a变化,b变化以及c变化。例如a,可以先算出等差数列下a位置的值,然后判断那个数值是否可以被a整除。

AC代码
#include<iostream>
#define TIE ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
using namespace std;
ll a,b,c,d,t; 
int main(){
    TIE;cin>>t;
    while(t--){
        cin>>a>>b>>c;
        d=c-b;
        if((b-d)>=a&&(b-d)%a==0){cout<<"YES\n";continue;}
        d=(c-a);
        if(d%2==0)
            if((a+d/2)>=b&&(a+d/2)%b==0){cout<<"YES\n";continue;}    
        d=b-a;
        if((b+d)>=c&&(b+d)%c==0){cout<<"YES\n";continue;}
        cout<<"NO\n";
    }
     return 0;
}

错因

本题在做的时候忽略了b+d>c或a的情况。

三、Division by Two and Permutation(除以2变成一种全排列)

题目描述

一个序列,每个元素都可以不断除以二并向下取整,问对每个元素进行若干次操作后,是否可以 

变成一个1~n的全排列数组。

思路

首先想到使用一个数组记录1~n的所有数,每个数除到n以下时,标记数组记录以下。若标记数组能将1~n全部记录下来,则可以。

但这个思路有一个问题,即当某个元素能同时除出两个n以下的数,且仅有这个元素能除出这两个数时,代码会判定为可以,但事实上却是不可以的。

为了处理这个问题,可以使用一个递推。

首先,标记数组需记录每个数出现次数。在标记完成之后,倒叙遍历标记数组。若出现未标记的数,直接判断no,若出现不为一且出现次数大于一的数,则继续除,并将新产生的数标记到前面的数组空间中。这样可以将多余的数填补不够用的空缺。

由此得到递推关系式:

b [ i /  2 ] + = b [ i ] - 1 ;

代码
#include<bits/stdc++.h>
#define TIE ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
using namespace std;
ll t,n,a,b[55],f;
signed main(){
	TIE;cin>>t;
	while(t--){
		cin>>n;memset(b,0,sizeof b);f=0;
		for(int i=1;i<=n;i++){
			cin>>a;
			while(a){if(a<=n)b[a]=1;a/=2;}
		}
		for(int i=n;i>=1;i++){
			if(!b[i]){f=1;break;}
			if(b[i]>1)b[i/2]+=b[i]-1;
		}
		if(f)cout<<"NO\n";
		else cout<<"YES\n";
	}
	return 0;
}
 错因

在找出初始思路问题后,未找到一个合适的方法解决此问题。

四、Palindromes Coloring(涂色构造回文串)

题目描述

给定一个由小写拉丁字母组成的字符串s,可以用 1到k中的颜色给一些字母涂色。不一定所有字母都涂上颜色,但每种颜色都至少有一个字母涂成该颜色。然后,任意调换涂有相同颜色的字母,调换次数不限。之后,就生成了k个字符串,其中 i个字符串将包含所有涂有第i 种颜色的字符。并按顺序写成一个字符串。
给字符串中的字符涂色,使生成的 k个字符串都是回文字符串,并且这些 k字符串中最短的字符串的长度最大。
 

思路

记录分别出现次数为偶数与奇数的字符数量。若是偶数,则除以k分配到k个字符串里。剩余的当作多出来的奇数看待,累加到奇数里。

AC代码
#include<bits/stdc++.h>
#define TIE ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
int t,n,k,a[130],ans;string s;
signed main(){
	TIE;cin>>t;
	while(t--){
		cin>>n>>k>>s;int even=0,odd=0;memset(a,0,sizeof a);
		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;}
		int ans=(even/k)*2;
		odd+=(even%k)*2;
		if(odd>=k)ans++;
		cout<<ans<<'\n';
	}
	return 0;
}

五、Masha-forgetful(小可记数字 )

题目描述

给定一个数字字符串s,再给定n个数字字符串,从这n个字符串中找一些片段拼成s。

输出分割方式。

思路

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值