gym 101908B Marbles 博弈论SG函数

http://codeforces.com/gym/101908/problem/B

题目大意:

一个100*100的棋盘,座标范围是[0, 100]的,上面有n个棋子。Alice 和 Bob轮流操作,每次操作可以把一枚棋子向左或者向下或者向斜下方移动任意步,也就是(x,y) 有这三种移动(x-l, y), (x, y-l), (x-l, y-l)。多个棋子可以同时在同一位置。第一个把棋子移动到(0, 0)点的人获胜。 问是否先手必胜。

 

问题分析:

看完题目我就想,这不就是个Nim游戏吗,求一下SG函数异或一下就完了。然而事情没有那么简单,交上去直接就WA了,然后就懵逼了。

其实问题也不是很复杂。该问题跟Nim游戏有个很大的区别,将Nim游戏的取石子问题转化到这个棋盘上的话,失败条件就是所有的棋子都在(0, 0)点,无法继续移动。而对该问题而言,你所面对的局面里面有任意一个棋子在(0, 0)点即视为失败。

那么就考虑把这个问题简单地转化为Nim游戏的模型。首先如果初始棋子有在x = 0, y = 0, y = x这三条线上的,特判一下输出Y。然后发现在游戏的过程中,将棋子移动到这三条线上就相当于必败,所有棋子肯定不选择移动到这三条线上。于是我们在计算SG函数的时候剔除掉这三条线。同时我们可以找到(1, 2)和(2, 1)这两个点,一旦棋子移动到这两个点,就无法继续移动了,否则对方就会获得胜利。那么(1, 2)和(2, 1)这两个点就对应着Nim游戏里的某一堆石子被取完了。最后的结束条件是所有的棋子都在(1, 2)或者(2, 1)了。至此,问题就转化为了普通的有向图Nim有戏。

总结出最后的解法:将终结态设为(1, 2)和(2, 1)两个点,SG函数值设为0。DFS求所有点的SG函数,过程中跳过两个座标轴以及y = x这条线上的点。将n个棋子的位置上的SG函数求异或,最后的结果是0就输出N,否则是Y

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章