Sicily1798. Alice and Bob[策略问题]

[原题描述]

Description

Bob is very famous because he likes to play games. Today he puts a chessboard in the desktop, and plays a game with Alice. The size of the chessboard is n by n. A stone is placed in a corner square. They play alternatively with Alice having the first move. Each time, player is allowed to move the stone to an unvisited neighbor square horizontally or vertically. The one who can’t make a move will lose the game. If both play perfectly, who will win the game?

Input

The input is a sequence of positive integers each in a separate line. The integers are between 1 and 10000, inclusive, indicating the size of the chessboard. The end of the input is indicated by a zero.

Output

Output the winner (“Alice” or “Bob”) for each input line except the last zero. No other characters should be inserted in the output.

Sample Input

2
0
Sample Output

Alice

解题思路:

这个是一个策略问题,往往这种题目用一般的算法都是很难解决的。但是用数学的方法可能会更好理解一点。
方法:用1*2形状的骨牌放整个图
解析:很多人可能会问了,为什么要用上面的骨牌呢?其实理由很简单。
这是一个双方博弈的问题。我们先要求Alice的起始点和第一步走的点可以形成一个1*2的骨牌(可以理解为一个矩形)。
上面的假设是合理的。因为移动方法只能是水平的,或者是垂直的。所以,结果是无论在起始点上选择怎么移动,都可以理解为是在一个已有的1*2的骨牌(矩阵内部移动)。
起始问题解决了
那么按照这样的思路,对于Bob要做的事情,就是不断地去从一个骨牌去找到新的骨牌,而,对于Alice就是在Bob已经找好的骨牌内部移动。
有人可能会问了,为什么确保了Bob进入的一定是一个骨牌呢?(就是说,为什么在Bob走完之后,Alice一定能走呢?)
这个问题很对,其实,这时候就需要判断了(而这个就是这个程序的唯一要考虑的地方)。
因为我们很清楚,一旦确保了Bob每次进入的都是一个新的没有走过的骨牌,那么Alice的百分百赢的。(Bob负责在找新的骨牌,找到了Alice就去骨牌的另外一个位置就好了嘛)
判断方法其实很简单,就是判断整个图是否可以被1*2的骨牌完全覆盖
图片1
先看上面的整个图片,这是一个4*4的正方形(题目说了,图都是正方形)
我们是能找到这样的一个图的用1*2的骨牌覆盖的方法的。就是如下:
图片2
这其实只是其中的一种分类方法。但已经说明了可以用1*2的骨牌进行完全覆盖。
要知道,Alice是负责在一个Bob已经走过的骨牌中走,保证了Bob不能在这个骨牌中走,让Bob如果不想输掉比赛,就必须要去找到新的骨牌。
上面是张”偶数偶数”的图,下面看一张”奇数奇数”的图
图片3
这个图是安排不了一个关于1*2的骨牌的全覆盖的。原因是奇数乘于奇数还是奇数。那么就不能被偶数整除。
图片4
像上图一样。
那么这时候情况就反过来了。之前我们说Alice只需要在Bob找到的骨牌中移动,确保了Bob不能走回到这个旧的骨牌就好了,那么最后Alice就是稳赢了。但上面的推理,其实在偶数的情况才成立
对于上面的一样,如果是奇数的呢?
我们就可以理解为,显示Alice在从起始点走,那么Bob就在Alice走过的那个骨牌内部走这样的假设合理的,因为在确保了这个图在减去一个点之后,是可以被一个1*2的骨牌全覆盖的时候,那么Bob就可以说是在原来的Alice走的骨牌上进行移动了,确保Alice不能在这个旧的骨牌内部走。

最终的代码:(只需要判断n是个奇数还是偶数就好了)

#include 
using namespace std;
int main(){
    int n;
    while (cin >> n && n) {
        cout << (n%2==0? "Alice\n":"Bob\n");
    }
}

最后,老套路,宣传一波自己的公众号!(求关注哇!)
本人中大一肥宅,欢迎大家关注,请扫下面的二维码(〃’▽’〃)


二维码

如果觉得有帮助的话,可以扫码,赞赏鼓励一下!谢谢!


这里写图片描述

你可能感兴趣的:(算法,C++)