比赛
时间: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。
输出分割方式。