acm--博弈入门1(巴什博弈1)--(HDU 1846 HDU 2049)

版权声明:看不懂请评论,我会积极改进的 https://blog.csdn.net/qq_36285879/article/details/53489553

一开始听大佬讲巴什博弈,听成巴士博弈,后来知道了巴什博弈的大名,还知道了博弈不止一种。所谓博弈,就是一场心机的对抗。

好巴什,好巴什。。。。。。(记得有一个广告语是这么来着)

切入正题:

巴什博弈,问题引入:

只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。假设你先取,你要怎样获胜呢?

首先,我们要找一个必赢的点,当然是剩下(m+1)个物品给对方,这样对方至少取一个,至多取m个,都取不完物品,而在他取完后,你可以获胜。

我们假设对手取k个,你只要取m+1-k个即可。

最后一步想好了, 最后倒数第二步,只要保证剩(m+1)个,同样,我们假设对手取k个,你只要取m+1-k个即可。

因此我们发现了如何取胜的法则:如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。总之,要保持给对手留下(m+1)的倍数,就能最后获胜。

那么一开始只要n%(m+1)!=0,先取者一定获胜。

来。来,来,水两题

HDU 1846

#include<stdio.h>
int main()
{
    int T, n, m;
    scanf("%d", &T);
    {
        while (T--)
        {
            int f = 0;
            scanf("%d%d", &n, &m);
            if (n <= m)
                f= 1;
            else if (n % (m + 1) != 0)
                f = 1;
            if (f == 1)
                printf("first/n");
            else
                printf("second/n");
        }
    }
    return 0;
}

HDU 2049

#include<stdio.h>
int main()
{
    int t, n, m;
    while(scanf("%d%d", &m,&n)==2)
    {
        int flag = 0;
        if (m <= n)
        {
            for (int i = m; i <= n; i++)
            {
                if (flag == 1)
                    printf(" ");
                printf("%d", i);
                flag = 1;
            }
            printf("\n");
        }
        else
        {
            if (m % (n + 1) == 0)
                printf("none\n");
            else
                printf("%d\n", m%(n+1));
        }

    }
    return 0;
}

下一课:浅谈P/N理论

猜你喜欢

转载自blog.csdn.net/qq_36285879/article/details/53489553
今日推荐