参考http://blog.csdn.net/gatevin/article/details/45341773
题目大意:
一:
就是现在有一个n*n的棋盘, 现在在一个角落有一个棋子, 两人轮流进行操作, 每次可以将这个棋子移动到相邻的没有走过的位置, 谁不能移动棋子谁就输了, 棋子相邻的位置时上下左右4个方向
大致思路:
刚开始看没什么感觉, 不过稍微画了一下之后就发现必胜策略了
首先如果n是偶数, n*n的棋盘刚好可以被2*1的砖块放满, 那么对于先手一定从2*1砖块的一端走到另外一端, 那么对于后手无论走到哪一个2*1砖块的一端, 先手都可以走到另一端, 最后无路可走的一定是后手
如果n是奇数, 那么n*n的棋盘恰好可以分割成2*1的砖块多一个起点, 那么先手无论走到哪一个2*1砖块的一端, 后手都有路可以走, 那么先手一定会变得无路可走
二
转自http://www.cnblogs.com/cchun/archive/2011/08/10/2520096.html
巴什博弈(定理献上):
只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个.最后取光者得胜.
n = (m+1)r+s , (r为任意自然数,s≤m), 即n%(m+1) != 0, 则先取者肯定获胜。
巴什博弈还是很好理解滴,以你是先手的角度考虑。你想把对手给弄垮,那么每一局,你都必须构建一个局势,这个局势就是每次都留给对手m+1的倍数个物品(为什么留给m+1倍就一定能赢,你稍微动动脑子就出来了)。所以不只是取物品中的博弈可以用到巴什定理,还可以是报数之类的,看谁先报到100.并且每次报的数必须是1~10(包括1跟10),那么你每次都应该留给对手剩下的报数个数为11的倍数。
当当,转到此题来。题目为:
1、 总共n张牌;
2、 双方轮流抓牌;
3、 每人每次抓牌的个数只能是2的幂次(即:1,2,4,8,16…)
4、 抓完牌,胜负结果也出来了:最后抓完牌的人为胜者;
如果你是先手,那么请考虑你的必胜点。由于规定只能去2的幂次,那么只要你留给对手的牌数为3的倍数时,那么你就必赢,因为留下3的倍数时,对手有两种情况:1,要么取剩下1,给你胜利 2,要么对手取了一点点儿,轮到你时,你就又可以构造一个3的倍数了嘛。 所以无论哪种情况,当你留给对手为3N的时候,你是必胜的。、
三
题意:一个n*m的表格,起始位置为右上角,目标位置为左下角,甲先开始走,走的规则是可以向左,向下或者向左下(对顶的)走一格。谁先走到目标位置谁就胜利。在甲乙都采用最佳策略的时候,先走者能否获胜。也是一个巴什博弈的题目。首先画出PN图,
如图就能很容易的看出,只要m或者n有一个是偶数先手就能必胜。
四
题意:
有两个相同的盒子,一个盒子里面有n个球,另一个盒子里面有1个球,每次清空球较少的那个盒子,然后从另外的一个盒子里拿到空盒子里使得操作后两个盒子至少有一个球,判断是先手还是后者胜;
思路:
跟每次拿走至少一个且不超过一半那个一样的sg函数;
打表:
void init() {
sg[0]=0;
sg[1]=0;
sg[2]=1;
for(int i=3;i<=1000;++i){
mem(vis,0);
for(int j=(i+1)/2;j<i;++j){
vis[sg[j]]=1;
}
for(int j=0;;++j){
if(!vis[j]){
sg[i]=j;break;
}
}
}
for(int i=1;i<=100;++i){
printf("%d : %d\n",i,sg[i]);
}
}
五
问题:首先有两堆石子,博弈双方每次可以取一堆石子中的任意个,不能不取,或者取两堆石子中的相同个。先取完者赢。
一些明显的必败状态(也就是当你面对这些状态时,只要你的对手够聪明,不犯错,无论你怎么拿,你都是必输的)(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
六
阶梯博弈(Staircase Nim)
POJ 1704
【题意】
从左到右有一排石子,给出石子所在的位置。规定每个石子只能向左移动,且不能跨过前面的石子。最左边的石子最多只能移动到1位置。每次选择一个石子按规则向左移动,问先手是否能赢。
【分析】
我们把棋子按位置升序排列后,从后往前把他们两两绑定成一对。如果总个数是奇数,就把最前面一个和边界(位置为0)绑定。
在同一对棋子中,如果对手移动前一个,你总能对后一个移动相同的步数,所以一对棋子的前一个和前一对棋子的后一个之间有多少个空位置对最终的结果是没有影响的。
于是我们只需要考虑同一对的两个棋子之间有多少空位。
这样一来就成了N堆取石子游戏了.
HDU 4315
【题意】
有N个人爬山,山顶坐标为0,其他人的坐标按升序给出。不同的坐标只能容纳一个人(山顶不限),Alice和Bob轮流选择一个人让他移动任意步,但不能越过前面那个人。现在有一个人是king(给出id),谁能将king移动到山顶就算赢。
【分析】
考虑King的情况和上述版本几乎一致,只要把King当作普通人一样处理即可。
除了两种特殊情况:
1. 当King是第一个人时,Alice直接胜
2. 当King是第二个人且一共有奇数个人时,第一堆的大小需要减1。
因为如果king在奇数石子上,那么king前面的那一对石子k1,k2.
当对方把k1移到top时,我可以把k2移到top前的一个位置.
那么对于k2石子,对方如果碰了它,那么我肯定会把king移到top的.
所以k2也相当于是一颗废子而已,不影响最终Nim的结果.