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<stdio.h>
#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]<p)   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;i<n;i++)
            scanf("%ld",&a[i]);
        quick_sort(a,n);
        long ans = a[n/2]-a[0];     //推导出的规律 
        for(i=1;i<n/2;i++)
            ans=min(ans,a[i+n/2]-a[i]); //找最小值 
        printf("%ld\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值