4171: Rhl的游戏
Description
RHL最近迷上一个小游戏:Flip it。游戏的规则很简单,在一个N*M的格子上,有一些格子是黑色,有一些是白色
每选择一个格子按一次,格子以及周围边相邻的格子都会翻转颜色(边相邻指至少与该格子有一条公共边的格子
),黑变白,白变黑。RHL希望把所有格子都变成白色的。不幸的是,有一些格子坏掉了,无法被按下。这时,它
可以完成游戏吗?
Input
第一行一个整数T,表示T组数据。
每组数据开始于三个整数n,m,k,分别表示格子的高度和宽度、坏掉格子的个数。接下来的n行,每行一个长度m的
字符串,表示格子状态为‘B‘或‘W‘。最后k行,每行两个整数Xi,Yi(1≤Xi≤n,1≤Yi≤m),表示坏掉的格子。
n,m,k<=256,T<=10
Output
对于每组数据,先输出一行Case #i: (1≤i≤T)
如果可以成功,输出YES,否则输出NO。
Sample Input
2
3 3 0
WBW
BBB
WBW
3 3 2
WBW
BBB
WBW
2 2
3 2
Sample Output
Case #1:
YES
Case #2:
NO
如果n,m的范围比较小,那么直接令$X_{i,j}$表示$(i,j)$格子按不按,然后直接高斯消元,不能按的限制等价于一个方程$X_{i,j}=0$
当n,m比较大的时候,直接高斯消元虽然可以利用他比较稀疏的特点优化时间,但空间还是比较卡。
这时考虑缩小变量规模,可以利用$X_{1,i}$表示出$X_{2,i}$进而将$X_{n,i}$表示出来,这样变量规模就缩小到了n的规模。
这依赖于一个等式,对于点$(i,j)$,有$$X_{i-1,j}\oplus X_{i,j}\oplus X_{i,j-1}\oplus X_{i,j+1}\oplus X_{i+1,j}\oplus map[i][j]=0$$
那么利用这个等式,就可以在已知第$i$行和$i-1$行的线性表示的情况下,表示出$i+1$行关于$X_{i,1…m}$的线性表示。
举个例子就是$X_{2,3}=X_{1,3}\oplus X_{1,2}\oplus X_{1,4}\oplus map[1][3]$,这里的$map[1][3]$表示$(1,3)$这个格子是$0\ or\ 1$
那么以此类推到最后一行后,就可以利用$(n,j)$点的等式来列出一个关于$X_{1,1…m}$的方程,总共有m个方程,m个未知数。
对于不能按的限制,由于已知了每个点的线性表示,那么也可以变成一个方程。最后高斯消元即可。
代码实现的时候只需要用一个$bitset$,$F[i][j]$表示$(i,j)$的线性表示中$X_{1,1…m}$的系数,另外用一个$int$数组记录一下$map[i][j]$的异或和即可。
总复杂度$O(T\frac{n^3}{32})$
代码:
1 |
|