[CF2147D]Game on Array题解

time limit per test

2 seconds

memory limit per test

256 megabytes

You are given an array a of n positive integers. Alice and Bob will play a game with this array. They will take alternating turns, with Alice going first.

At each turn, the player must choose a value x>0 that appears in a at least once. Then,

  1. the player earns 1 point for each value x in the array,
  2. each value x in the array is decreased by 1 and becomes x−1.

Note that the player can choose x only if it is present in a at the moment, so each valid move earns a positive amount of points. For example, if the array is [3,8,5,8] and Alice chooses x=8, the array will become [3,7,5,7] and Alice will earn 2 points.

The game ends when no x can be chosen; that is, when all the elements in the array are zero.

Given that both players want to maximize their points and play optimally, calculate the amount of points that each player will end up with.

有道 翻译

给定一个包含 n 个正整数的数组 a 。爱丽丝和鲍勃将用这个数组玩一个游戏。他们轮流来,爱丽丝先来。

在每一回合,玩家必须选择在 a 中至少出现一次的值 x>0 。然后,

  1. 玩家从数组中的每个值 x 中获得 1 点,

  2. 数组中的每个值 x 都减去 1 ,变成 x−1 。

注意,玩家只能在 a 中出现 x 时选择 x ,所以每个有效的移动都可以获得正数的点数。例如,如果数组是 [3,8,5,8] ,爱丽丝选择 x=8 ,数组将变成 [3,7,5,7] ,爱丽丝将获得 2 点。

当不能选择 x 时游戏结束;也就是说,当数组中的所有元素都为零时。

考虑到两名玩家都想要最大化自己的分数并获得最佳效果,我们便需要计算出每名玩家最终能够获得的分数。

Input

Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤103). The description of the test cases follows.

The first line of each test case contains an integer n (1≤n≤2⋅105) — the size of the array.

The second line contains n integers a1,a2,…,an (1≤ai≤109) — the elements of the array.

It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

有道 翻译

输入** **

每个测试包含多个测试用例。第一行包含测试用例的数量 t ( 1≤t≤103 )。下面是测试用例的描述。

每个测试用例的第一行包含一个整数 n ( 1≤n≤2⋅105 )——数组的大小。

第二行包含 n 个整数 a1,a2,…,an ( 1≤ai≤109 )——数组的元素。

保证所有测试用例 n 的和不超过 2⋅105 。

Output

For each test case, output two integers, the amount of points Alice and Bob will get if both play optimally.

有道 翻译

** **输出

对于每个测试用例,输出两个整数,如果Alice和Bob都玩得最优,他们将得到的点数。

Example

Input

Copy

 

3

3

2 1 1

5

3 3 3 5 5

4

9 9 9 9

Output

Copy

 

3 1

10 9

20 16

Note

Visualizer link

In the first test case, Alice chooses x=1 with her first move. The array becomes [2,0,0] and she earns 2 points. After that, Bob is forced to choose x=2. The array becomes [1,0,0] and Bob earns 1 point. Finally, Alice is forced to choose x=1 and earn one more point. After that, the array is [0,0,0], so the game ends. In total, Alice finishes with 3 points and Bob with 1 point.

In the third test case, each player will decrement all the elements and earn 4 points each move. Alice will earn 5⋅4=20 points while Bob will only earn 4⋅4=16 points.

有道 翻译

注意

(可视化工具链接)(https://codeforces.com/assets/contests/2147/D_L6mCC2TWFOxWZySjNzRU.html)

在第一个测试用例中,Alice第一步选择了 x=1 。数组变成 [2,0,0] ,她得到 2 点。之后,Bob被迫选择 x=2 。数组变成 [1,0,0] ,Bob获得 1 点。最后,爱丽丝被迫选择 x=1 并获得多一分。之后,数组为 [0,0,0] ,因此游戏结束。总的来说,Alice得到 3 分,Bob得到 1 分。

在第三个测试用例中,每个玩家将递减所有元素并在每次移动中获得 4 点。Alice将获得 5⋅4=20 点,而Bob将只获得 4⋅4=16 点。

思路

贪心即可。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long t,n,a[200005],b[200005],c[200005],ac=0,lk=0,kl=0,wf=0;
int main(){
	cin>>t;
	while(t--){
		cin>>n;
		b[0]=0;
		c[0]=0;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			b[i]=0;
			c[i]=0;
		}
		sort(a+1,a+n+1);
		ac=0;
		for(int i=1;i<=n;i++){
			if(i==1){
				ac=1;
			}
			else if(a[i]==a[i-1]){
				ac++;
			}
			else{
				b[ac]+=a[i-1];
				ac=1;
			}
		}
		b[ac]+=a[n];
		lk=kl=0;
		wf=0;
		for(int i=n;i>=1;i--){
			if(b[i]!=0){
				if(b[i]%2==0){
					lk+=(b[i]/2)*i;
					kl+=(b[i]/2)*i;
				}
				else{
					if(wf==0){
						lk+=(b[i]/2+1)*i;
						kl+=(b[i]/2)*i;
						wf=1;
					}
					else{
						lk+=(b[i]/2)*i;
						kl+=(b[i]/2+1)*i;
						wf=0;						
					}
				}
			}
		}
		cout<<lk<<" "<<kl<<endl;
	}
	return 0;
}

posted @ 2025-10-16 10:50  bz02_2023f2  阅读(8)  评论(0)    收藏  举报  来源