Codeforces Hello 2024

A. Wallet Exchange

  • 博弈

每人每次可移除任意钱包里的一枚硬币,不能移除的玩家失败,Alice先手,硬币数量a+b为奇数则Alice获胜,否则Bob获胜。

AC代码

#include<iostream>
#include<set>
#include<cstring>
#include<queue>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
long long read(){
	long long x=0,w=1;
	char c=getchar();
	while(!isdigit(c)){
		if(c=='-')w=-1;
		c=getchar();
	}
	while(isdigit(c)){
		x=(x<<1)+(x<<3)+(c&15);
		c=getchar();
	}
	return x*w;
}


int main(){
	int t=read();
	while(t--){
		int a=read(),b=read();
		if((a+b)&1)cout<<"Alice\n";
		else cout<<"Bob\n";
	}
}

B. Plus-Minus Split

  • 贪心

+ 1 +1 +1 − 1 -1 1可以抵消,剩下的 + 1 +1 +1 − 1 -1 1划分成长度为 1 1 1的若干数组,使得数组总和 s u m sum sum以及数组长度 m m m最小,得到每个数组的最小值,各个最小值相加得到最终答案的最小值。

AC代码

#include<iostream>
#include<set>
#include<cstring>
#include<queue>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
long long read(){
	long long x=0,w=1;
	char c=getchar();
	while(!isdigit(c)){
		if(c=='-')w=-1;
		c=getchar();
	}
	while(isdigit(c)){
		x=(x<<1)+(x<<3)+(c&15);
		c=getchar();
	}
	return x*w;
}


int main(){
	int t=read();
	while(t--){
		int n=read();
		string s;cin>>s;
		int zero=0,one=0;
		for(char c:s){
			if(c=='-')++zero;
			else ++one;
		}
		cout<<abs(one-zero)<<endl;
	}
}

C. Grouping Increases

  • 贪心

将数组分为两个子序列,使得连续上升序列数总和最小。
将数组分为 b b b c c c数组,用 x x x y y y分别表示数组最后一个元素,并规定 x ≤ y x \leq y xy

  1. a i ≤ x a_i \leq x aix a i a_i ai无论加入到 b b b或者 c c c数组,惩罚值 p e n a l t y penalty penalty都不会增加,将其加入进较小元素的数组中,以保留较大的元素。
  2. y < a i y < a_i y<ai a i a_i ai无论加入到 b b b或者 c c c数组, p e n a l t y penalty penalty都会增加 1 1 1,将其加入进较小元素的数组中,以保留较大的元素。
  3. x < a i ≤ y x < a_i \leq y x<aiy a i a_i ai加入 x x x所在数组会使 p e n a l t y penalty penalty增加 1 1 1,而加入 y y y所在的数组 p e n a l t y penalty penalty不会增加,故将其加入较大元素的数组中,以避免 p e n a l t y penalty penalty的增加。第一种情况与第二种情况保留较大元素正是为了此刻的较大元素 y ≥ a i y ≥ a_i yai的可能性更大,降低 y < a i y < a_i y<ai导致 p e n a l t y penalty penalty必须增加的可能性,故此刻应该发挥较大元素 y y y的作用避免 p e n a l t y penalty penalty的增加。

AC代码

#include<iostream>
#include<set>
#include<cstring>
#include<queue>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
long long read(){
	long long x=0,w=1;
	char c=getchar();
	while(!isdigit(c)){
		if(c=='-')w=-1;
		c=getchar();
	}
	while(isdigit(c)){
		x=(x<<1)+(x<<3)+(c&15);
		c=getchar();
	}
	return x*w;
}

int main(){
	int t=read();
	while(t--){
		int n=read();
		int a;
		int min1=INT32_MAX,min2=INT32_MAX;
		int ans=0;
		for(int i=0;i<n;++i){
			a=read();
			if(min1>min2)swap(min1,min2);
			if(a<=min1)min1=a;
			else if(min2<a){
				min1=a;
				++ans;
			}
			else min2=a;
		}
		cout<<ans<<endl;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值