十字翻转棋的解法(高斯消元法)
来源:互联网 发布:mcs-51单片机寻址方式 编辑:程序博客网 时间:2024/04/29 05:51
翻转棋带给我的启发
——布尔方程&高斯消元法
今天上午上软件工程需求建模课,觉得乏味,开始玩起游戏。无意间看到徐浦手机上的翻转棋游戏,于是便一发不可收拾的去思考最佳解法。
翻转棋游戏,是一类智益游戏:5×4的方格,每个格子黑色或者红色,如下图
点击某一个方格,那么此格子的上下左右格子以及它本身 颜色都取反。于是,问怎么点击才可以使得所有的格子都变成红色?
在纸上模拟了好几次,发现存在最小的点击次数。因为某个格子点一次和点3次效果一样,于是开始思考这个问题的解法。最典型的当然是暴力,20个格子,时间复杂度O(2^n)。显然格子再多一点就不靠谱。既然格子只有两个状态,那么,所有的运算都是布尔运算。而且考虑到,在一个格子上点击两次其实没变化,于是可以做出推断,最多只需要点击20次就可以得出所需要的状态。那么如何做呢?
我的方法是:用x(i)表示第i个方格是否需要点击。X(i)只取0或1,取1代表这个格子需要点击,取0则不需要点击。问题转换为如何求解x向量。现在我们需要加约束,因为所有格子都需要变成红色。不妨假设,红色的状态为0,黑色的状态为1。那么就是点击某些格子,让所有的x(i)变成0。
接下来列方程:
假设格子的原始状态为s(i),对于第一个方格:x(1)^x(2)^x(5)^s(1)=0。等式的意思就是说,对于第一个格子,如果要使它变成0,那么只能是点击1、2、5三个方格起作用。而如果x(1)取1,那么方格状态取反,刚好用异或操作(^)就可以解决;如果x(1)取0,异或0没有什么影响。
于是对于所有的格子,我们都列出一个布尔方程。二十个方程对应二十个变量{x(1)…x(20)},猜测方程有唯一解。然后求解的时候需要变形。
x(1)^x(2)^x(5)^s(1)=0 ==> x(1)^x(2)^x(5)=s(1)
然后,对于方程组,由于只含有异或操作,于是可以用高斯消元法求解。
比如说:
x(1)^x(2)^x(5)=a (1)
x(1)^x(2) =b (2)
==>对(1)(2)取异或得到(3)
x(1)^x(2)^x(5) ^ x(1)^x(2)=x(5)=a^b (3)
这个和高斯消元法的思路非常像,于是问题就搞定了~~~
分析一下解方程的时间复杂度:高斯消元法的复杂度,O(n^2),比原来的暴力要快。
- 十字翻转棋的解法(高斯消元法)
- 关于十字翻转棋的解法研究
- 翻转字符串的解法
- 一款“翻转”小游戏的解法
- 新解法之翻转句子中单词的顺序(不用两次翻转,用两个指针)
- 3303 翻转区间 伸展树的解法
- 剑指offer42:翻转单词顺序 VS 左旋转字符串(更高效、简便的解法)
- 链表翻转的迭代和递归解法
- 字符串操作,翻转句子中单词的顺序--经典面试题两种解法
- 十字链表(写的很漂亮呀!)
- 十字链表(写的很漂亮呀!)
- 十字链表求顶点的度(有向图)
- (15)稀疏矩阵的压缩-十字链表
- 稀疏矩阵 的 压缩存储 (十字链表形式)
- 字符串的翻转(递归)
- string字符串的翻转---(子字符串不翻转)问题
- 图的十字链表
- 矩阵的十字链表
- 我看外汇储备
- Spring 框架的设计理念与设计模式分析
- makefile(1)
- Linux下Makefile的automake生成全攻略
- java减少数据访问层代码—反射3—数据访问层就一个接口一个实现
- 十字翻转棋的解法(高斯消元法)
- 对Bridge模式的理解
- ASP.net--Web服务端控件
- 写得蛮好的linux学习笔记!!!
- Windows Store apps开发[30]移动控件位置
- Sublime Text 快捷键
- 用户量决定一切......
- 杭电OJ——1006 Tick and Tick
- JVM调优系列(一):总结 -Xms -Xmx -Xmn -Xss