POJ 2811:熄灯问题 GO实现

98 阅读1分钟

使用字符数组来表示灯矩阵,每个字符的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
    }
    
    

}

}