CF594A Warrior and Archer 题解

由于本人在思索了很久后才把本题思路打通,所以为了帮助像我一样没有非常理解解法的人,我打算再将解法非常详细地叙述一遍,如果您无法理解解法,请跟着我再一步步将题目捋顺。

Step.1 解题意

题目要求其实很好理解,共给出 n n n 个点的位置,A,B两个人轮流取点,A要求最后剩下的两个点尽量近,B要求最后剩下的两个点尽量远。

Step.2 推一推

在这过程中,有一些东西可以被推知,这里做出详细的解释(由于解释太过于精细,dalao们请自行忽视):

  1. 一共有几个点?显然 n n n

  2. 最后剩下几个点?显然 2 2 2

  3. 综合 1 , 2 1,2 1,2,可知两人一共取走了 n − 2 n-2 n2 个点

  4. 显然,两人取走的点是一样多的。也就是说,由于他们一共取走 n − 2 n-2 n2 个点,因此 A A A B B B 两人分别取走了 n − 2 2 \dfrac{n-2}{2} 2n2 个点。而学过小学数学的人都知道:
    n − 2 2 = n 2 − 2 2 = n 2 − 1 \dfrac{n-2}{2}=\dfrac{n}{2}-\dfrac{2}{2}=\dfrac{n}{2}-1 2n2=2n22=2n1
    所以,两人分别取走了 n 2 − 1 \dfrac{n}{2}-1 2n1个点

5. A A A 会取哪些点? B B B 会取哪些点?这是理解本题的关键。首先有两个点能使A,B两人的收益同时最大(这不废话吗),但这两个点是固定的,即当数据给出时便已经确定。所以A为了使两点距离尽量近,会选择取走两点左右的点,更具体说,他会选择去掉端点位置的点。而B要使两点距离尽量远,会选择去掉两点中间位置的点。这里要注意的是,由于这两个点同时保证了A,B两人的利益最大化,所以两人都不会选择去掉这个点。

  1. 如何确定两点位置?这是构造代码的核心。这其实很好理解。尤其是我们已经得出了上面的结论。由于B只会取两点之间的点且B取了 n 2 − 1 \dfrac{n}{2}-1 2n1 个点(前文已推知),因此最后剩下两点之间的距离为 ( n 2 − 1 ) + 1 = n 2 (\dfrac{n}{2}-1)+1=\dfrac{n}{2} (2n1)+1=2n,即两点间距离等于点数加一,详情可以参照小学奥数:植树问题。(注意这里假设每个点间距离为 1 1 1)。设较近的点距离为 k k k,则较远的点距离为 k + n 2 k+\dfrac{n}{2} k+2n

Step.3 码一码(构造代码)

我们知道了剩余两个点的位置关系,就可以通过枚举第一个点的位置,得到第二个点的位置,得到两点间的距离。那如何确定当前枚举的情况是好的呢?由于A先取,具有先手优势,于是我们应当取两个点之间的距离最小值。
需要注意的一点是,在枚举之前,由于输入的序列没有单调性,于是我们应先将其排序。

代码如下:

#include <bits/stdc++.h>

#define endl '\n'

using namespace std;

const int N = 2e5 + 5;

int n;
int a[N];

int ans = (1 << 30);

signed main() {
	
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	
	cin >> n;
	for(int i = 1; i <= n; i ++) {
		cin >> a[i];
	}
	
	sort(a + 1, a + n + 1);
	
	for(int i = 1; i <= (n >> 1); i ++) {
		ans = min(a[i + (n >> 1)] - a[i], ans);
	}
	
	cout << ans << endl;
	
	return 0;
}

这里对位运算作出解释: ( n > > 1 ) (n>>1) (n>>1) 代表 n n n 二进制右移一位,等价于 n 2 n\over 2 2n
写的这么认真,还不点赞吗?
求过QWQ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值