- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我试图解决一个编程问题,但我无法看到一个有效的算法。情况是这样的:我们有一套n
可以打开的灯 (1)
或关闭 (0)
像这样:1110001011101
.该字节串表示有 13
灯形成一个圆圈,其中前三个灯亮,然后 3
下关等和circle
意味着最后一盏灯在第一盏灯旁边。
然后我们得到了一个整数 m>0
.这意味着在任何时候我们都可以选择一盏灯,然后选择它和它的m adjacent
灯改变状态 s to 1-s
. IE。如果 m=2
和灯状态是 1110001011101
然后将该过程应用于第一盏灯,我们得到序列 0000001011110
.
现在的问题是,如果字符串的长度约为 2200
和 m
关于 110
是固定的,如何开发algorithm
那个shut downs all
灯带 minimum
转弯数量?
最佳答案
这个问题类似于众所周知的“熄灯”问题。 http://en.wikipedia.org/wiki/Lights_Out_%28game%29一种方法是使用线性代数。使用较小的数字更容易理解,例如长度 = 5 和 m = 1。
首先请注意,选择一盏灯并更改它(及其邻居的)状态两次没有任何影响。其次请注意,灯(及其邻居)的开关顺序无关紧要。因此,策略只是一组灯。我们将用 1 表示被选择作为策略一部分的灯和未被 0 选择的灯。我们将 1 和 0 放在列向量中,例如,(0 1 1 0 1)^T
其中 T 用于转置(行变成列)。该策略意味着在位置 1(当然从位置 0 开始)及其两个相邻位置切换灯;然后是位置 2 的灯和它的两个邻居,最后是位置 4 的灯和它的两个邻居。
策略的效果可以通过域 GF(2) 上的矩阵乘法来计算。 GF(2) 只有 2 个元素,0
和 1
, 除了规则 1 + 1 = 0
之外,还有普通的算术规则.那么上面策略的效果就是矩阵乘以一个矩阵,结果是选择灯i
在 i-th
列,换句话说,由“循环矩阵”组成,如下所示:
[ 1 1 0 0 1 ] [0] [0]
[ 1 1 1 0 0 ] [1] [0]
[ 0 1 1 1 0 ] [1] = [0]
[ 0 0 1 1 1 ] [0] [0]
[ 1 0 0 1 1 ] [1] [1]
(0 1 1 0 1)^T
是只切换最后一个位置的灯。因此,如果您开始时只点亮最后一个位置的灯并应用该策略,则所有灯都将关闭。
b
表示初始配置。 .解决方案策略则是一个列向量
x
满足矩阵方程
Ax = b
.
b
, 1) 是否存在满足
Ax=b
的 x ? 2)是解决方案
x
独特的?如果没有,哪个
x
最少
1
的? 3)如何计算?
b
都有唯一的解。 .我们可以获得
b
的解决方案形式
(0 0 ... 1 ... 0)^T
,换句话说,通过“旋转”解
(0 1 1 0 1)^T
,一个 1,其余的为零.我们可以将任何解决方案唯一地表示为这些解决方案的线性组合,因此具有最小数量 1 的策略/解决方案与任何给定初始状态的唯一解决方案相同。
(100100)^T
,
(010010)^T
, 和
(001001)^T
映射到结果
(111111)^T
,因此在某些情况下没有唯一的解决方案;根据线性代数理论,在其他一些情况下没有解。
[ 1 1 0 0 1 ] [1 0 0 0 0] [ 1 1 0 0 1 ] [1 0 0 0 0]
[ 1 1 1 0 0 ] [0 1 0 0 0] [ 0 0 1 0 1 ] [1 1 0 0 0]
[ 0 1 1 1 0 ] [0 0 1 0 0] -> [ 0 1 1 1 0 ] [0 0 1 0 0] ->
[ 0 0 1 1 1 ] [0 0 0 1 0] [ 0 0 1 1 1 ] [0 0 0 1 0]
[ 1 0 0 1 1 ] [0 0 0 0 1] [ 0 1 0 1 0 ] [1 0 0 0 1]
[ 1 1 0 0 1 ] [1 0 0 0 0] [ 1 0 1 1 1 ] [1 0 1 0 0]
[ 0 1 1 1 0 ] [0 0 1 0 0] [ 0 1 1 1 0 ] [0 0 1 0 0]
[ 0 0 1 0 1 ] [1 1 0 0 0] -> [ 0 0 1 0 1 ] [1 1 0 0 0] ->
[ 0 0 1 1 1 ] [0 0 0 1 0] [ 0 0 1 1 1 ] [0 0 0 1 0]
[ 0 1 0 1 0 ] [1 0 0 0 1] [ 0 0 1 0 0 ] [1 0 1 0 1]
[ 1 0 0 1 0 ] [0 1 1 0 0] [ 1 0 0 0 0 ] [1 0 1 1 0]
[ 0 1 0 1 1 ] [1 1 1 0 0] [ 0 1 0 0 1 ] [0 0 1 1 0]
[ 0 0 1 0 1 ] [1 1 0 0 0] -> [ 0 0 1 0 1 ] [1 1 0 0 0] ->
[ 0 0 0 1 0 ] [1 1 0 1 0] [ 0 0 0 1 0 ] [1 1 0 1 0]
[ 0 0 0 0 1 ] [0 1 1 0 1] [ 0 0 0 0 1 ] [0 1 1 0 1]
[ 1 0 0 0 0 ] [1 0 1 1 0]
[ 0 1 0 0 0 ] [0 1 0 1 1]
[ 0 0 1 0 0 ] [1 0 1 0 1]
[ 0 0 0 1 0 ] [1 1 0 1 0]
[ 0 0 0 0 1 ] [0 1 1 0 1]
b
.如果没有独特的策略,您将如何最小化移动次数?
关于algorithm - 找到关闭灯的最少按下次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30006809/
我是一名优秀的程序员,十分优秀!