TopCoder SRM 558 DIV2 Level 3:CatAndRabbit

来源:互联网 发布:速达软件功能 编辑:程序博客网 时间:2024/05/17 07:13

题目:http://community.topcoder.com/stat?c=problem_statement&pm=12187

题目大意:给定N个瓷砖(分为黑色和白色), A先走, A,B 轮流走,规则如下:选择一个黑色瓷砖,选择向左还是向右走X步(X为任意步,只能走在黑色瓷砖上),每走过一步将白色瓷砖反转至黑色瓷砖。如果没有白色瓷砖,则判为负。 给定N个瓷砖的分布,求A赢还是B赢。1<=N<=50

解题思路:

刚看到题目,觉得这是个典型的博弈论问题。必胜态: 存在一步操作使得状态变为必败态; 必败态:所以的有效操作都能到必胜态。所以觉得采用动态规划求解,但是时间复杂度较高,O(N * 2^N).

后来看解题报告:http://apps.topcoder.com/wiki/display/tc/SRM+558

假设白色瓷砖为1,黑色瓷砖为0,白色瓷砖将黑色瓷砖分为若干个连续的子段,即A1, A2, ...,Ak. 那么一步有效操作变为:从A1,A2, ...,Ak中选择一个Ai, 减去x个1。

所以该问题转化为博弈论中典型问题NIM问题: http://en.wikipedia.org/wiki/Nim

结论:XOR操作为异或操作, 如果p = A1 xor A1 xor A2, ... ,xor Ak 不等于0, 那么该状态为先手的必胜态,否则为必败态。

为什么?必胜态: 存在一步操作使得状态变为必败态; 必败态:所以的有效操作都能到必胜态。

当A1=A2=,...,=Ak=0时,p= 0, 记为状态S0, 显然是个必败态, 则上一个任意能到S0的状态为必胜状态,此时p必不等于0.

反之当p!=0时, 总存在一次步骤将下一个状态的p变为0. 为什么? 来证明一下,假设p= A1 xor A1 xor A2, ... ,xor Ak 不等于0,则二进制表示为: bq,bq-1,...,b0, bq = 1, q为二进制最高位为1的长度。 则A1,A2,...,Ak中至少存在Ai,其q位为1的,否则bq不可能等于1. 如果将Ai变为Ai', Ai'的q位置为0,q-1,q-2,...,0位分别置为bq-1',bq-2',...,b0'. 其中bq-1',bq-2',...,b0' = p的q-1,q-2,...,0 XOR Ai的q-1,q-2,...,0

显然 Ai' < Ai, 符合操作规则, 使得只需要操作一步将p!=0 变为0.

C
#include <string>using namespace std;class CatAndRabbit {public:string getWinner(string tiles) {//avoid a speciall case when the Cat cannot move at the first time.if (tiles.find('#') == string::npos) return "Rabbit";//calculate the sum xor of all the consecutive-white-tile segments.int sum_xor = 0, pr = 0;for (int i = 0; i < tiles.size(); i++)if (tiles[i] == '.') pr++;else sum_xor ^= pr, pr = 0;sum_xor ^= pr;//Cat will lose when sum_xor > 0;return sum_xor? "Cat": "Rabbit";}};

++ Code (解题报告)