CF1878补题

比赛

比赛:Codeforces Round 900(Div.3)

做题时间:2023.11.13~2023.11.18

成绩:做过一道,补过四道

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

一、How Much Does Daytona Cost?

题目描述

t组数据,每组数据给出一个长度为n的序列a和一个数字k。判断a中是否存在一个非空子段使得k在这个子段中出现次数最多。存在输出 YES,否则输出 NO

评测忽略大小写。例如,yEsYesyesYES 都表是肯定回答。

思路

只要a序列中有k,那么k自己就可以构成一个非空子段,因此本体只需要判断a序列中是否有k即可。

AC代码

#include<bits/stdc++.h>
using namespace std;
int t,n,a,k,f;
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d %d",&n,&k);f=0;
		for(int i=1;i<=n;i++){
			scanf("%d",&a);
			if(a==k)f=1;
		}
		if(f)printf("yes\n");
		else printf("NO\n");
	}
	return 0;
}

本题比赛时直接AC

二、Aleksa and Stack

题目描述

有t组数据,每组数据给定n。你构造一个长度为n的数组a,使得该数组满足a[i−1]​+a[i−2]​∤3×a[i]​。

思路

当a为奇数序列时,a[i-1]与a[i-2]都为奇数,所以a[i-1]+a[i-2]为偶数。但a[i]为奇数,所以3xa[i]也为奇数,而偶数必然不被奇数整除,因此本题只需要输出一个长度为n的奇数序列即可。

AC代码

#include<bits/stdc++.h>
using namespace std;
int t,n; 
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		for(int i=1,j=1;i<=n;i++,j+=2)printf("%d ",j);printf("\n");
	}
	return 0;
}

 这道题一开始没想出来怎么构造数组,所以没做,讲过了之后补ac的。

三、Vasilije in Cacak

题目描述

有t组数据,每组数据给定n,k,x。判断能否在1∼n 中不重复的恰好选出k个数使得这k个数的和为x。

可以选出输出 YES,否则输出 NO

评测忽略大小写。例如,yEsYesyesYES 都表是肯定回答。

思路

1~n这n个数中取出k个,最小的和为前,k个数之和,最大的和为后k个数之和。

因此,当x < k(k+1)/2或x > k(2n-k+1)/2时,一定不成立。

而在k(k+1)/2~k(2n-k+1)/2之间的和,必然都能被取到。因为若能求和出x,必然能求和出x+1。

AC代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll t,n,k,x; 
int main(){
	scanf("%lld",&t);
	while(t--){
		scanf("%lld %lld %lld",&n,&k,&x);
		if(x<k*(k+1)/2||x>k*(2*n-k+1)/2)printf("NO\n");
		else printf("YES\n");
	}
	return 0;
}

这道题比赛时候没看,上课讲过之后补上的

四、Reverse Madness

题目描述

给一个长度为n的字符串s,以及一个k和两个k大小的数组l,r

保证:l[1]=1,r[k]=n,l[i]<r[i],l[i]=r[i-1]+1

q次操作

每个修改都用一个正整数x来定义:
找出一个索引 i,使得 l[i]<=x<=r[i],让a=min(x,r[i]+l[i]-x),b=max(x,r[i]+l[i]-x)

将字符串s从a到b反转

打印最终结果

思路

每个[l[i],r[i]]区间互不相交。

当子段被反转时,修改x与修改n-x+1是一样的。且对于任意区间,当修改偶数次时相当于没修改,所以只需统计每个点被修改的次数即可。

AC代码

#include <bits/stdc++.h>
#define TIE ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
using namespace std;
const int N=2e5+5;
int t,n,k,a[N],b[N],cnt[N],q,x;string s;
int main(){
	TIE;cin>>t;
	while (t--){
		cin>>n>>k>>s;memset(cnt,0,sizeof cnt);
		for(int i=0;i<k;i++){cin>>a[i];a[i]--;}
		for(int i=0;i<k;i++){cin>>b[i];b[i]--;}
		cin>>q;
		for(int i=0;i<q;i++){cin>>x;cnt[x-1]++;}
		string ans="";
		for(int i=0;i<k;i++){
			string s1=s.substr(a[i],b[i]-a[i]+1);
			int sm=0,l=a[i],r=b[i];
			for(int j=l;j<=(l+r)/2;j++){
				sm+=cnt[j]+cnt[r-j+l];
				if(sum&1)swap(s1[j-l],s1[r-j]);
			}
			ans += s1;
		}
		cout<<ans<< '\n';
	}
	return 0;
}

这道题也是比赛的时候没看,上课讲了补上的。 

五、Iva & Pav

题目描述

给定n大小的数组a,定义f(l,r)为a[l]&a[l+1]&...&a[r]。

q次查询,每次有k和l,输出最大的r使得f(l,r)>=k.

思路

这道题首先要用前缀和。f[i][j]表示前i个中j个比特出现的次数。若f[r][j]-f[l-1][j]=r-l+1,那么第j个应出现在区间[l,r]的所有元素中。

后面的并没有成功完成,代码也没有写出来。

这道题比赛的时候没看,赛后也没补过。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值