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("
");
		}
		else
		{
			if (m % (n + 1) == 0)
				printf("none
");
			else
				printf("%d
", m%(n+1));
		}

	}
	return 0;
}

下一课:浅谈P/N理论

原文地址:https://www.cnblogs.com/juicebox/p/7529235.html