码迷,mamicode.com
首页 > 其他好文 > 详细

P2252 取石子游戏

时间:2019-08-20 09:11:34      阅读:102      评论:0      收藏:0      [点我收藏+]

标签:数字   输入   开始   cstring   off   main   bsp   can   pac   

题目背景

题目描述

有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。

输入格式

输入共一行。

第一行共两个数a, b,表示石子的初始情况。

输出格式

输出共一行。

第一行为一个数字1、0或-1,如果最后你是胜利者则为1;若失败则为0;若结果无法确定则为-1。

输入输出样例

输入 #1
8 4
输出 #1
1

说明/提示

[数据范围]

50%的数据,a, b <= 1000

100%的数据,a, b <= 1 000 000 000

思路

这道题就是典型的威佐夫博弈(Wythoff Game)

一. 巴什博奕(Bash Game):

A和B一块报数,每人每次报最少1个,最多报4个,看谁先报到30。这应该是最古老的关于巴什博奕的游戏了吧。

其实如果知道原理,这游戏一点运气成分都没有,只和先手后手有关,比如第一次报数,A报k个数,那么B报5-k个数,那么B报数之后问题就变为,A和B一块报数,看谁先报到25了,进而变为20,15,10,5,当到5的时候,不管A怎么报数,最后一个数肯定是B报的,可以看出,作为后手的B在个游戏中是不会输的。

那么如果我们要报n个数,每次最少报一个,最多报m个,我们可以找到这么一个整数k和r,使n=k*(m+1)+r,代入上面的例子我们就可以知道,如果r=0,那么先手必败;否则,先手必胜。

二. 威佐夫博弈(Wythoff Game):

有两堆各若干的物品,两人轮流从其中一堆取至少一件物品,至多不限,或从两堆中同时取相同件物品,规定最后取完者胜利。

直接说结论了,若两堆物品的初始值为(x,y),且x<y,则另z=y-x;

记w=(int)[((sqrt(5)+1)/2)*z ];

若w=x,则先手必败,否则先手必胜。

三. 尼姆博弈(Nimm Game):

尼姆博弈指的是这样一个博弈游戏:有任意堆物品,每堆物品的个数是任意的,双方轮流从中取物品,每一次只能从一堆物品中取部分或全部物品,最少取一件,取到最后一件物品的人获胜。

结论就是:把每堆物品数全部异或起来,如果得到的值为0,那么先手必败,否则先手必胜。

四. 斐波那契博弈:

有一堆物品,两人轮流取物品,先手最少取一个,至多无上限,但不能把物品取完,之后每次取的物品数不能超过上一次取的物品数的二倍且至少为一件,取走最后一件物品的人获胜。

结论是:先手胜当且仅当n不是斐波那契数(n为物品总数)

(源自 混沌

代码:

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

long long a,b;

int main () {
	scanf("%lld%lld",&a,&b);
	if(a>b)
		swap(a,b);
	int tmp=abs(a-b);
	int ans=tmp*(1.0+sqrt(5.0))/2.0;
	if(ans==a)
		printf("0\n");
	else
		printf("1\n");
	return 0;
}

 

P2252 取石子游戏

标签:数字   输入   开始   cstring   off   main   bsp   can   pac   

原文地址:https://www.cnblogs.com/mysh/p/11380714.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!