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

时间:2023-03-09 06:37:50
acm--博弈入门1(巴什博弈1)--(HDU 1846 HDU 2049)

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

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

切入正题:

巴什博弈,问题引入:

只有一堆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理论