#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=2e5+10,M=0,Z=1e9+7,ms63=1061109567;
int n;
int a[N];
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
sort(a+1,a+n+1);
int ans=2e9;
int dis=n/2;
for(int i=1;i+dis<=n;++i)gmin(ans,a[i+dis]-a[i]);
printf("%d\n",ans);
}
return 0;
}
/*
【trick&&吐槽】
这题非常地有趣,当时比赛的时候不知道哪里出错误了,竟然没人AC。
虚拟赛的时候成了第二个过题的,233333
【题意】
给你n(2<=n<=2e5且n为偶数)个位置,每个位置的取值范围都在[0,1e9],且所有位置两两不同。
A和B轮流选数,A先手,一共操作(n-2)/2轮次,直到最后只剩下2个数为止。
A希望使得剩下的2个数之差(绝对值)尽可能小,B希望使得剩下的2个数之差(绝对值)尽可能大。
A、B两人都用最优策略。问你,最后剩下的2个数之差(绝对值)是多少。
【类型】
博弈 贪心 脑洞
【分析】
这道题很有趣,并不是传统的博弈。
我们可以按照模拟的思路入手——
首先,A想要使得数尽可能接近,他肯定去除的是最小或最大的数。
这个很显然成立,因为如果对于a[first]或a[last],如果不把这个数移除,那么它最终就是剩下的两个数之一。
也就是说,我们早晚要去除这个边界的数。
这个博弈是没有局部性质的,也就是,移除数字的先后并不重要,我们使得最终的决策集合相同即可。
于是可以认定A一定移除边界的数。
而B呢?B想要使得两个数尽可能远,他肯定去除的是中间的数。
我们换一种说法——
A想要使得两个数尽可能近,而这两个数的下标距离,再小也不能小于n/2。
B想要使得两个数尽可能远,而这两个数的下标距离,再大也不能超过n/2。
于是最后博弈出的两个数的下标距离,就会恰好是n/2
A可以决定的是,最后剩下哪两个这种要求的数。
于是我们暴力扫描一遍,gmin(ans,a[i+dis]-a[i]),这道题就做完啦!
【时间复杂度&&优化】
O(n)
*/
【Codeforces Round 330 (Div 2)C】【博弈 贪心 脑洞】n个数AB轮流选到只剩俩,A希望差小B希望差大问最后差值
最新推荐文章于 2022-11-03 17:12:57 发布