Training Before the Olympiad

Good Bye 2023
C. Training Before the Olympiad
题目链接

题意:

给你n和大小为n的数组a,masha和olya在上面玩一个游戏,轮到某人时,如果剩下的数多于两个,那么可以任选两个数 a i a j a_i a_j aiaj合并成 ⌊ a i + a j 2 ⌋ ⋅ 2 \lfloor \frac{a_i + a_j}{2} \rfloor \cdot 2 2ai+aj2。两人轮流进行,masha先手。

masha希望最后剩下的数最大,olys希望最后剩下的数最小,问最后剩下的数是什么。

对每个 k = 1 , 2 , 3 … n k=1,2,3\dots n k=1,2,3n,输出前a数组取前k个数的最后的结果。

思路:

应该是推结论的题,不然对每个k都需要 l o g n logn logn以内来推,不太可能

考虑这个运算,如果是奇偶数相加,会导致整除2再乘2会丢一个1,而其他情况没有问题,所以对olya来说,她想让最后留下的数最小,就需要尽量合并奇数和偶数。那么对masha,她肯定要阻止olya合并奇偶数,所以她前面就要合并两个奇数来不断减少奇数的个数。

合并后一定会剩偶数,所以不用管偶数,偶数一直是够用的。masha和olya一轮下来,奇数会损失三个,总和会损失1。如果最后奇数不够一轮用的,剩两个会被masha合并,无损,剩一个会被olya合并,损失1。

所以累加一下前i个数,记为tot,再记录一下奇数个数cnt,那么结果就是tot-cnt/3-(cnt%3==1)

code:

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
 
int T,n;
 
int main(){
	cin>>T;
	while(T--){
		cin>>n;
		ll cnt=0,tot=0;
		for(int i=1,t;i<=n;i++){
			cin>>t;
			tot+=t;
			if(t&1)cnt++;//odd counter
			if(i>1)cout<<tot-(cnt/3)-(cnt%3%2)<<" ";
			else cout<<tot<<" ";
		}
		puts("");
	}
	return 0;
}
  • 19
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值