文章目录
一、概况
比赛名称: 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 1∼n 的全排列。
2 大体思路
输入后,遍历整个序列,并创建一个标记数组。对于每个数,首先将该数反复除,直至处于 1 − N 1-N 1−N 范围内且曾经没有出现过(标记数组中该值的下标上的数为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 可以分为字符 h
、 a
和成对的 bb
, zz
。
所以就可以统计字符串中成对的字符的数量和成单的字符的数量,最后计算即可。
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;
}
}
}