A--Warrior and Archer

题意:
n个数,俩人轮流删除数,使得最后剩下2个
A(先手) 希望距离最小,B(后手) 希望距离最大

思路:
博弈问题,设最后两个点为 a 、b
由于A先行动,那么结果一定对 A最有利
A希望两个点尽量近,那么他会删两边的点,他不可能删[a,b]内的点
B则相反,他不可能去删[a,b]外的点
这样 [a,b]中的点一定都是 B删的,有 N/2-1个点,
[a,b]之外的同理由A删掉
所以最后,a - b + 1 = N/2 - 1

ps:语文不好 尽力了
pps:冒泡超时贼难受

#include
#define N 200010

long min(long a, long b)
{
    if(a > b)   return b;
    else        return a;
}

void quick_sort(long *a, long n)    //快速排序 (递归) 
{
    long i,j,temp;
    if(n<2)       return;           //当只有一个数字就直接返回 
    long p=a[n/2];                  //获取数组中间位置的数
    for(i=0,j=n-1;;i++,j--)         //两端逼近 
    {
        while(a[i]//寻找a[i]>=p 
        while(a[j]>p)   j--;        //寻找a[j]<=p 
        if(i>=j)        break;      //i、j重合时结束 
        temp=a[i];a[i]=a[j];a[j]=temp;
        //由于a[i] > p > a[j] 交换 准备下次循环 
    }
    quick_sort(a,i);                //左半边重排 
    quick_sort(a+i,n-i);            //右半边重排 
}
int main()
{
    long a[N];
    long n,i;
    while(scanf("%ld",&n)!=EOF)
    {
        for(i=0;iscanf("%ld",&a[i]);
        quick_sort(a,n);
        long ans = a[n/2]-a[0];     //推导出的规律 
        for(i=1;i2;i++)
            ans=min(ans,a[i+n/2]-a[i]); //找最小值 
        printf("%ld\n",ans);
    }
    return 0;
}

你可能感兴趣的:(博弈问题)