这又是一个经典的Nim游戏的缩影,博弈问题如果不是找规律的话,我们就要仔细分析他的动向和他们的构成。Nim游戏是非常经典的游戏案例。由此而来的游戏千变万化,但是万变不离其中,只要你想通这其中的奥秘,发现里面的端倪,就可以举一反三。那么你也就真正会这种博弈了。
典型的Nim博弈是这么说的:
定义:有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法的移动)。
那么这里也是一样的,我们可以将你自己的一个棋子可以移动的地方的个数称之为“这一堆的石子的数量”。那么两个人走这么一行的格子就好比是在去取一堆的石头。那么这时候这就自然变成Nim博弈。当然这里有一点技巧就是:如下如所示:
分别有三个红1,三个黑1.代表双方。那么黑子先走就胜利。黑子第一步走第一行的往前走两格,这个时候红子就输了。那么这两个字符中间的空格就相当于是石子数,这时候红方可以网后走,但是不管你怎么走都是输。所以这里想说的就是当你们中间格子的数量已经可以决定双方的胜负色的时候,双方后面的格子就是没有用的。就是不要难过考虑的,这样的话,这道题就变成赤裸裸的Nim游戏了。下面大家应该知道怎么做了吧。不过还是贴一下AC的代码:
#include<iostream> using namespace std; #include<cstdlib> #include<cmath> const int Max=1005; int a[Max]; int b[Max]; int main() { int n,m; int leap=0; int k,i; int num; while(cin>>n>>m) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); num=0; leap=0; k=n; for(i=0;i<n;i++) cin>>a[i]>>b[i]; for(i=0;i<n;i++) { num^=(abs(a[i]-b[i])-1); } if(num!=0) cout<<"I WIN!"<<endl; else cout<<"BAD LUCK!"<<endl; } return 0; }