【ZJOI2009】染色游戏
【题目描述】
一共n×m个硬币,摆成n×m的长方形。dongdong和xixi玩一个游戏,每次可以选择一个连通块,并把其中的硬币全部翻转,但是需要满足存在一个硬币属于这个连通块并且所有其他硬币都在它的左上方(可以正左方也可以正上方),并且这个硬币是从反面向上翻成正面向上。dongdong 和xixi 轮流操作。如果某一方无法操作,那么他(她) 就输了。dongdong 先进行第一步操作,假设双方都采用最优策略。问dongdong 是否有必胜策略。
【输入】
第一行一个数T,表示他们一共玩T 局游戏。接下来是T 组游戏描述。每组游戏第一行两个数n;m,接下来n 行每行m 个字符,第i 行第j 个字符如果是“H” 表示第i 行第j 列的硬币是正面向上,否则是反面向上。第i 行j 列的左上方是指行不超过i 并且列不超过j 的区域。
【输出】
对于每局游戏,输出一行。如果dongdong 存在必胜策略则输出“-_-”(不含引号) 否则输出“=_=”(不含引号)。(注意输出的都是半角符号,即三个符号ASCII 码分别为45,61,95)
【输入样例】
3
2 3
HHH
HHH
2 3
HHH
TTH
2 1
T
H
【输出样例】
=_=
-_-
-_-
【数据范围】
对于40% 的数据,满足1 ≤ n;m ≤ 5。
对于100% 的数据,满足1 ≤ n;m ≤ 100,1 ≤ T ≤ 50。
【题解】
翻硬币游戏的二维版,结论可以从一位拓展而来。
一维翻硬币游戏中,局面的SG值为局面中每个反面朝上的棋子单一存在时的SG值的异或和,并且若局面只有第x个棋子反面朝上,则局面SG值为lowbit(x)。
根据数学归纳法,可以证明这个结论前半部分对二维也成立(想不通就动手画一画吧)。枚举二维时每个反面棋子单一朝上的情况,打表找规律>_<,我们发现若设左上角坐标为(0,0),这个单一存在的棋子不在第一行和第一列且坐标为(x,y)时,局面SG值为2^(x+y)(这个的数学证明蒟蒻只能OTL,但找到这个规律还是很容易的),由此,我们可以得到二维翻硬币游戏的SG值公式:
SG(i,j)=lowbit(i+j+1),i*j=0;
SG(i,j)=2^(i+j),i*j≠0。
还没完,题目中说n和m均小于100,但2^(n+m)=2^200,早就爆long long了。可以使用高精度,但考虑到lowbit和2的幂数值的特殊性,我们选择以二进制来保存局面SG值。由于最终的SG值二进制一定不超过200位,所以每个局面判断一下最后的SG值是否至少有一位为1即可。
【代码】
有了上述结论,基本就是秒杀了O(∩_∩)O~