NYOJ博弈系列-取石子

如果步了解博弈,请先去看看基本的博弈知识。

http://blog.csdn.net/niushuai666/article/details/6638943


NYOJ上博弈类题目链接:

http://acm.nyist.net/JudgeOnline/keysearch.php?key=%E5%8F%96%E7%9F%B3%E5%AD%90


第一个:巴什博弈

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=23


解题思路:

模板题。


代码如下:

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

int main()
{
	int N, num, limit;
	scanf("%d", &N);
	while(N--)
	{
		scanf("%d%d", &num, &limit);
		if(num % (limit + 1) != 0)
			printf("Win\n");
		else
			printf("Lose\n");
	}
	return 0;
}        

第二个:威佐夫博弈


题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=161


解题思路:

模板题。(这道题题目有点问题,威佐夫博弈第一种取法要求至少取1个石子,要不然没法继续了= =)


代码如下:

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

int main()
{
	int num1, num2, tmp;
	while(scanf("%d%d", &num1, &num2) != EOF)
	{
		if(num1 > num2)
			swap(num1, num2);
		tmp = floor((num2 - num1) * (1 + sqrt(5.0)) / 2.0);

		if(tmp == num1)	
		    printf("0\n");
		else	
		    printf("1\n");
	}
	return 0;
}

第三个:尼姆博弈+巴什博弈


题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=135


解题思路:

这道题是巴什博弈和尼姆博弈的杂糅,因为尼姆博弈要求对每一堆石子可以取1-全部,而这道题限制了个数,就成为了巴什博弈。那为什么可以用尼姆博弈的思想来求解呢?

因为我们可以发现,当我们使用巴什博弈取到最后一次时,得到的n%(m+1)结果肯定<m,这样就符合了尼姆博弈的要求,进而可以用尼姆博弈的异或运算来求解。


代码如下:

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

int bashi(int m, int n)
{
	return m % (n + 1);
}

int main()
{
	//freopen("Input.txt", "r", stdin);
	int ncase, num, i, pernum, limit, ans;
	scanf("%d", &ncase);
	while(ncase--)
	{
		ans = 0;
		scanf("%d", &num);
		for(i = 0; i < num; ++i)
		{
			scanf("%d%d", &pernum, &limit);
			ans ^= bashi(pernum, limit);
		}
		if(ans) 
		    printf("Win\n");
		else 
		    printf("Lose\n");
	}
	return 0;
}    

其他两道就有难度了,分别为楼教主出的神题,斐波那契博弈。

等研究了再来写一下。

你可能感兴趣的:(NYOJ博弈系列-取石子)