本文介绍: 所以先手的策略为:选择两个奇偶性相同的数相加,如果有两个以上的奇数就会选两个奇数(因为先手做一次操作会产生一个偶数,而先手肯定想要后手操作次数尽可能的少,且后手做一次操作要一奇一偶,但偶数数量已经不能减少(先手自己要操作),所以只能让奇数变少)。可以得知后手策略为:选择两个奇偶性不同的数相加,否则任选两数相加。,则剩下的一个奇数还会跟偶数操作一次所以还要减。可以发现如果两数奇偶性相同则。即为减一的个数,注意如果。我们可以发现一轮操作需要。个奇数,而且总和会减。,所以可以前缀奇数个数。,但如果奇偶性不同则。

洛谷题目链接

vjudge题目链接

Codeforces题目链接

分析

可以发现如果两数奇偶性相同则

a

i

+

a

j

2

2

lfloor frac{a_i + a_j}{2} rfloorcdot2

2ai+aj2 等于

a

i

+

a

j

a_i+a_j

ai+aj,但如果奇偶性不同则

a

i

+

a

j

2

2

lfloor frac{a_i + a_j}{2} rfloorcdot2

2ai+aj2 等于

a

i

+

a

j

1

a_i+a_j-1

ai+aj1

可以得知后手策略为:选择两个奇偶性不同的数相加,否则任选两数相加。

所以先手的策略为:选择两个奇偶性相同的数相加,如果有两个以上的奇数就会选两个奇数(因为先手做一次操作会产生一个偶数,而先手肯定想要后手操作次数尽可能的少,且后手做一次操作要一奇一偶,但偶数数量已经不能减少(先手自己要操作),所以只能让奇数变少)。

我们可以发现一轮操作需要

3

3

3 个奇数,而且总和会减

1

1

1,所以可以前缀奇数个数

c

n

t

cnt

cnt 和前缀和

p

r

e

pre

pre

c

n

t

÷

3

cntdiv3

cnt÷3 即为减一的个数,注意如果

c

n

t

cnt

cnt

3

3

3 等于

1

1

1,则剩下的一个奇数还会跟偶数操作一次所以还要减

1

1

1

代码

#include <bits/stdc++.h>
#define int long long

using namespace std;

const int N = 1e5 + 5;
int T, n, a[N];

signed main(){
	for(cin >> T; T; T --){
		cin >> n;
		for(int i = 1; i <= n; i ++){
			cin >> a[i];
		}
		int pre = a[1], _ = a[1] & 1;
		cout << a[1] << " ";
		for(int i = 2; i <= n; i ++){
			pre += a[i];
			if(a[i] & 1){
				_ ++;
			}
			cout << pre - _ / 3 - (_ % 3 == 1) << " ";
		}
		cout << "n";
	}
	return 0;
}

原文地址:https://blog.csdn.net/zc2000911/article/details/135396219

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_51792.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注