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 
#include 
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;
}

你可能感兴趣的:(错题本,算法,c++)