Codeforces Round 919 (Div. 2) (A-D)

文章讲述了三个编程题目:A.求满足特定条件的区间个数,B.Alice和Bob的游戏策略导致的数组和最大化/最小化问题,C.分割数组并寻找对应元素对m取余相等的分数。涉及了区间处理、数组操作和优化策略。
摘要由CSDN通过智能技术生成

A. Satisfying Constraints

题意:

求大于等于 x x x,小于等于 y y y,且不等于 z z z这个区间的个数。

思路

记录最大的 x x x,最小的 y y y,求出大于等于 x x x且小于等于 y y y z z z的个数 t e m p temp temp,答案就是 y − x − t e m p + 1 y-x-temp+1 yxtemp+1

代码

#include<iostream>
#include<algorithm>
#include<cstring>
 
#define int long long
 
using namespace std;
 
const int N=1010;
int st[N];
int t;
 
void solve(){
	int temp=0;
	int sum=0;
	int ans=0;
	int n;
	cin>>n;
	memset(st,false,sizeof(st));
	int mn=-0x3f3f3f3f;
	int mx=0x3f3f3f3f;
	while(n--){
		int a,b;
		cin>>a>>b;
		if(a==1) mn=max(mn,b);
		else if(a==2) mx=min(mx,b);
		else if(a==3) st[temp++]=b;
	}
	for(int i=0;i<temp;i++) if(st[i]>=mn&&st[i]<=mx) sum++;
	
	if(mn>mx) cout<<"0"<<endl;
	else cout<<mx-mn+1-sum<<endl;
}
signed main(){
	cin>>t;
	
	while(t--)
		solve();
	
	return 0;
}

B. Summation Game

题意:

Alice和Bob在玩一个游戏,给出一个数组Alice可以选择小于等于k个元素删除,Bob可选择小于等于x个元素乘于-1,Alice先进行操作,Alice希望最后的数组之和最大,Bob希望数组之和最小,假设双方都以最佳方式进行游戏,请找出游戏结束后数组元素的总和。

题解:

因为Bob希望最小,所以Bob会选择当前数组的x个最大值乘-1,所以如果Alice会选择最大的值进行删除,所以Alice要么不删除,要么选最大的删除,Bob只会选择最大的乘-1;结论:Alice会选择小于等于k个数删除,Bob一定会选择x个数乘-1。所以只需要枚举删除个数的取值。

代码

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N=2e5+10;
int a[N];
int t;
bool cmp(int  x,int y){
	return x>y;
}
void solve(){
	int n,k,x;
	
	memset(a,0,sizeof(a));
	cin>>n>>k>>x;
	
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=n;i++) a[i]+=a[i-1];
	int ans=-0x3f3f3f3f;
	for(int i=0;i<=k;i++){
		ans=max(ans,a[n]-2*a[min(n,i+x)]+a[i]);
	}
	cout<<ans<<endl;
}
int main(){
	cin>>t;
	
	while(t--) solve();
	
	return 0;
}

C. Partitioning the Array

题意:

将数组分成长度相等的子数组,若存在m使得每个子数组的对应元素对m取余后相等,则alice得到一分,输出alice最终得到的分数

思路:

因为对应元素对m取余后对应相等,所以对应元素的差值等于k倍的m(k为整数),所以所有元素对应的差值的最大公约数即为m,当m不等于1时则分数加一

代码:

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N=2e5+10;
int a[N];
int t;

void solve(){
	int n;
	cin>>n;
	int ans=0;
	for(int i=1;i<=n;i++) cin>>a[i];
	
	for(int k=1;k<=n;k++){
		if(n%k==0){
			int temp=0;
			for(int i=1;i+k<=n;i++){
				temp=__gcd(temp,abs(a[i+k]-a[i]));
			}
			if(temp!=1) ans++;
		}
	}
	cout<<ans<<endl;
}
int main(){
	cin>>t;
	
	while(t--) solve();
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值