题目链接
这道题是威佐夫博弈的一道入门题,问的十分简单,就是套威佐夫博弈的两个公式即可,因此顺带说说威佐夫博弈,威佐夫博弈和巴什博奕的场景很类似,所以索性就套用我在巴什博奕那篇文章中所描述的的那个场景。有两个二货,比赛拿XX(XX可以是任何东西,只要能定量拿走就好),只是这一次他们不再将XX混为一堆,而是作为两堆(两堆XX的数量均任意个),然后拿走的方式也改为: 1,从一堆里拿,可以拿任意数量个。2,从两堆里分别拿相等数量个。这两种方式二选一,但至少拿走一个XX,若谁取走最后一个XX,谁就赢了。是不是场景变得比巴什博奕麻烦了那么一丢丢啊~~~~
那么问题来了,如何取胜呢,,,(以下论述均是我参考了百度百科上的论述所写的,如果大家觉得写的太难看,可以直接参照百度百科上的:威佐夫博弈)
首先,我们标记一下这两堆石头:(a,b),其中a表示当前状态第一堆的数量,b表示当前状态第二堆的数量,(这里我要强调一点:就是这两堆XX它们的价值是等价的,它们是可以互换的,并不一定说第二堆的数量一定比第一堆多,这一点在后续论述中是有一定作用的)。
然后百科上对于(a,b)也给了一个特定的名称叫做“局势”,然后给出一些明显的必败状态(也就是当你面对这些状态时,只要你的对手够聪明,不犯错,无论你怎么拿,你都是必输的)(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)、...... 、(ak,bk) (k = 0, 1, 2, 3,......)。并称这些必败状态为“奇异局势”(至于为什么要叫奇异局势......额......不太清楚,忽略吧~)接下来的工作就是找出这些奇异局势的特点并总结规律。
然后就会得到a0=b0=0,ak是未在前面出现过的最小自然数,而 bk= ak + k。然后公式化就得到了奇异局势的状态公式:
ak = [ k * (1 + √5) / 2 ] , ([x]表示对x取整,也就是 (int)x )
bk = ak + k
按百科上所说,奇异局势有三个性质——
性质1:每个自然数都包含在且只包含在一个奇异局势中。
证明:因为ak为在其之前的奇异局势中未出现过的最小的自然数,所以ak的取值一直是保证在之前状态未出现过的数中的最小值,所以每一个当前状态的ak都要比之前的状态的ak要大,即ak>ak-1(k-1是下标),还想不通。。。不要紧,,把k和k-1带入上面ak的公式,这总能接受吧~~~~但ak不一定比bk-1大,看上面给出的几组奇异局势就不难看出。又bk=ak+k>ak-1+(k-1)=bk-1,所以对于任意的奇异状态(ak,bk)之前的状态中一定未出现过其中的数字,但ak取值是自动取当前未出现过的最小的数字,所以每一个自然数都一定会出现,故性质得证。
性质2:对任意的奇异局势,任何合法的操作都会使其成为非奇异局势,也就是奇异局势的所有后继状态均为非奇异局势。
证明:①若只从一堆里取XX,那么另一堆得数量没变,由性质1知,这个没变的自然数只会出现在当前的奇异局势中,所以当另一堆发生变化时,改变后得到的状态一定是非奇异局势。
②若从两堆里取相同数量的XX,那么由于 bk - ak = k (由公式得),所以他们之间的差值是不会变的,又因为对于任意的奇异局势它的两堆之间的差值是唯一值k,所以这种取法后的状态仍旧是非奇异局势。故性质得证。
性质3:任何非奇异局势都可以通过某种合法操作得到奇异局势,即奇异局势的所有后继状态中存在奇异局势。
证明:对于任意的一个非奇异局势(x,y),由性质1知:任何自然数均会出现在一个奇异局势中,所以要么 x = ak,要么 y = bk (k ∈ { 0, 1, 2, 3, 4, 5, .......}),所以分类讨论:
①若x = ak,y > bk,那么y减去(y - bk)即可得到奇异局势(ak , bk).
②若x = ak,y < bk,那么两堆同时减掉x-a(y-x) (y-x为下标),得到奇异局势(a(y-x) , a(y-x)+y-x).
③若x > ak,y = bk,那么x减去(x - ak)即可得到奇异局势(ak , bk).
④若x < ak,y = bk,这时又要对该状况细化分类讨论:
情况(1): x = aj , (j < k),此时从y中拿走(y - bj)即可得到奇异局势(aj , bj),
情况(2): x = bj , (j < k),此时从y中拿走(y - aj)即可得到奇异局势(aj , bj).
这里的④为什么要分类呢?这就要注意上文中我曾提到的强调点,这两堆是等价值的,也就是情况(2)得到奇异局势其实是(bj , aj),此时第一堆是比第二堆多的,为了同意奇异局势的格式才把它写成(aj , bj)。所以细化分类讨论的其实是对操作后 第一堆多余第二堆 和 第二堆多余第一堆 的两种情况进行讨论。这样性质3也得证。
好了,解释了这么多,回到此题正解,这道题就是套上述的ak和bk的公式,若符合奇异局势,则先手输,否则先手胜,输出对应结果即可。
#include
#include
#include
#include
#include
using namespace std;
int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
int n, m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int a=min(n,m);
int b=max(n,m);
double k=(double)b-a;
int term=(int)(k*(1+sqrt(5))/2);
if(term==a)
printf("0\n");
else
printf("1\n");
}
return 0;
}