CF div.3 寒假训练题解

C. Long Jumps

Polycarp found under the Christmas tree an array a of n elements and instructions for playing with it:

At first, choose index i (1≤i≤n) — starting position in the array. Put the chip at the index i (on the value ai).
While i≤n, add ai to your score and move the chip ai positions to the right (i.e. replace i with i+ai).
If i>n, then Polycarp ends the game.
For example, if n=5 and a=[7,3,1,2,3], then the following game options are possible:

Polycarp chooses i=1. Game process: i=1⟶+78. The score of the game is: a1=7.
Polycarp chooses i=2. Game process: i=2⟶+35⟶+38. The score of the game is: a2+a5=6.
Polycarp chooses i=3. Game process: i=3⟶+14⟶+26. The score of the game is: a3+a4=3.
Polycarp chooses i=4. Game process: i=4⟶+26. The score of the game is: a4=2.
Polycarp chooses i=5. Game process: i=5⟶+38. The score of the game is: a5=3.
Help Polycarp to find out the maximum score he can get if he chooses the starting index in an optimal way.

Input
The first line contains one integer t (1≤t≤104) — the number of test cases. Then t test cases follow.

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

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

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

Output
For each test case, output on a separate line one number — the maximum score that Polycarp can get by playing the game on the corresponding array according to the instruction from the statement. Note that Polycarp chooses any starting position from 1 to n in such a way as to maximize his result.
Example

input
4
5
7 3 1 2 3
3
2 1 4
6
2 1000 2 3 995 1
5
1 1 1 1 1

output
7
6
1000
5

解题思路: 刚开始写的时候我就直接从头开始暴力加,用循环,只要i<=n,就一直往i上加a[i],显然这题我理解错了,应该是i+a[i]后以此为下标,再判断a[i+a[i]]是否大于n,因此此题不应该选择从i=0开始遍历,而是选择i=n-1。
这样每次指针往前移动,第i个数所进行的add操作就相当于,第i个数加上第i+a[i]个数,此时第i+a[i]个数已经进行完add操作并将score储存在另一个数组中,即第i+a[i]个数加上第i+a[i]+a[i+a[i]]个数…(以此类推)。这有点类似于递归的思想,因此需要从数组后端往前端推。以下为代码:

#include<iostream>
#include<algorithm>
using namespace std;
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		int a[n],m[n],s=0;
		for(int i=0;i<n;i++) cin>>a[i];
		for(int i=n-1;i>=0;i--){
			m[i]=a[i];
			if(i+a[i]<n) m[i]+=m[i+a[i]]; //此步为add操作
			s=max(s,m[i]); //选择最大的一个数
			//cout<<m[i]<<endl;
		}
		cout<<s<<endl;
	}
	return 0;
}

D. Even-Odd Game

During their New Year holidays, Alice and Bob play the following game using an array a of n integers:

Players take turns, Alice moves first.
Each turn a player chooses any element and removes it from the array.
If Alice chooses even value, then she adds it to her score. If the chosen value is odd, Alice’s score does not change.
Similarly, if Bob chooses odd value, then he adds it to his score. If the chosen value is even, then Bob’s score does not change.
If there are no numbers left in the array, then the game ends. The player with the highest score wins. If the scores of the players are equal, then a draw is declared.

For example, if n=4 and a=[5,2,7,3], then the game could go as follows (there are other options):

On the first move, Alice chooses 2 and get two points. Her score is now 2. The array a is now [5,7,3].
On the second move, Bob chooses 5 and get five points. His score is now 5. The array a is now [7,3].
On the third move, Alice chooses 7 and get no points. Her score is now 2. The array a is now [3].
On the last move, Bob chooses 3 and get three points. His score is now 8. The array a is empty now.
Since Bob has more points at the end of the game, he is the winner.
You want to find out who will win if both players play optimally. Note that there may be duplicate numbers in the array.

Input
The first line contains an integer t (1≤t≤104) — the number of test cases. Then t test cases follow.

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

The next line contains n integers a1,a2,…,an (1≤ai≤109) — the array a used to play the game.

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

Output
For each test case, output on a separate line:

“Alice” if Alice wins with the optimal play;
“Bob” if Bob wins with the optimal play;
“Tie”, if a tie is declared during the optimal play.

Example

input
4
4
5 2 7 3
3
3 2 1
4
2 2 2 2
2
7 8

output
Bob
Tie
Alice
Alice

解题思路:此题刚开始没看出来规律,后来发现其实就是将数组从大到小排序,再由Alice先手,依次拿元素,并判断能否加入总分即可,以下为代码:

#include<iostream> 
#include<algorithm>
const int N=200005;
long long a[N];
using namespace std;
bool cmp(long long a,long long b){
	if(a<b) return a>b;
}
int main(){
	int t;
	cin>>t;
	while(t--){
		long n;
		long long sum1=0,sum2=0;
		cin>>n;
		for(long long i=0;i<n;i++) cin>>a[i];
		sort(a,a+n,cmp);
		for(long long i=0;i<n;i++){
			if(i%2==0){
				if(a[i]%2==0) sum1+=a[i];
			}
			else{
				if(a[i]%2!=0) sum2+=a[i];
			}
		}
		cout<<sum1<<" "<<sum2<<endl;
		if(sum1>sum2) printf("Alice\n");
		else if(sum1==sum2) printf("Tie\n");
		else printf("Bob\n");
	}
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值