使用字符数组来表示灯矩阵,每个字符的6个比特分别代表一行中的6盏灯。 GetBit, SetBit, 和 Flip 函数使用位运算来操作单个灯的状态。 首先读取输入,将初始灯状态存储在 oriLights 数组中。 然后遍历第一行开关的所有可能状态(2^6 = 64种)。 对每种状态,从第一行开始向下处理: 将当前行的开关状态复制到结果数组。 根据开关状态改变当前行的灯。 如果不是最后一行,则改变下一行的灯。 用当前行的灯状态作为下一行的开关状态。 如果最后一行的灯全部熄灭,则找到了解决方案。 当找到解决方案时,输出结果并退出循环。
package main
import(
"fmt"
)
const (
ROWS = 5
COLS = 6
)
func getBit(c byte, i int) int {
return int((c >> uint(i)) & 1)
}
func setBit(c *byte, i int, v int) {
if v != 0 {
*c |= 1 << uint(i)
} else {
*c &^= 1 << uint(i)
}
}
func flip(c * byte, i int) {
*c ^= 1 << uint(i)
}
func outputResult(result []byte) {
for i := 0; i < ROWS; i++ {
for j := 0; j < COLS; j++ {
fmt.Print(getBit(result[i], j))
if j < COLS - 1 {
fmt.Print(" ")
}
}
fmt.Println()
}
}
func main(){
var oriLights [ROWS]byte
var lights [ROWS]byte
var result [ROWS]byte
var switchs byte
for i := 0; i < ROWS; i++ {
for j := 0; j < COLS; j++ {
var t int
fmt.Scan(&t)
setBit(&oriLights[i], j, t)
}
}
for n := 0; n < 64; n++ {
copy(lights[:], oriLights[:])
switchs = byte(n)
for i := 0; i < ROWS; i++ {
result[i] = switchs
for j := 0; j < COLS; j++ {
if getBit(switch, j) != 0 {
//改变左灯
if j > 0 {
flip(&light[i], j - 1);
}
//改变开关位置灯泡
flip(&light[i], j);
//改变右灯泡
if j < COLS - 1 {
flip(&light[i], j + 1);
}
}
}
if i < ROWS - 1 {
lights[i + 1] ^= switchs
}
switchs = lights[i]
}
if lights[ROWS - 1] == 0 {
outputResult(result[:])
break
}
}
}