技巧:
在(特殊数)探测的结果下进行贪心找出最优解。(只关注数字二进制下01串的含义)
思路:
利用 0000000 和 11111111 通过所有门探测结果。
贪心法拆解结果找到每一位上最划算的数是0还是1。
得到的结果若不在m范围内则通过位运算再次找到一个最划算的值。
实现:
package main
import (
"fmt"
"math"
)
type Door struct {
op string
t int
}
func main() {
var n, m int
fmt.Scan(&n, &m)
arr := make([]Door, n)
zeroSeq, oneSeq := 0, int(^uint32(0)>>1)
for i := 0; i < n; i++ {
fmt.Scan(&arr[i].op, &arr[i].t)
if arr[i].op == "AND" {
zeroSeq &= arr[i].t
oneSeq &= arr[i].t
} else if arr[i].op ==&nbs***bsp;{
zeroSeq |= arr[i].t
oneSeq |= arr[i].t
} else {
zeroSeq ^= arr[i].t
oneSeq ^= arr[i].t
}
}
// 得到最优的二进制数
ans := buildBestSeq(zeroSeq, oneSeq, m)
// 带入获取结果
for i := 0; i < n; i++ {
if arr[i].op == "AND" {
ans &= arr[i].t
} else if arr[i].op ==&nbs***bsp;{
ans |= arr[i].t
} else {
ans ^= arr[i].t
}
}
fmt.Println(ans)
}
// case1 0 -> 0 1 -> 0 // 0
// case2 0 -> 0 1 -> 1 // 1
// case3 0 -> 1 1 -> 0 // 0
// case4 0 -> 1 1 -> 1 // 0
func buildBestSeq(zeroSeq, oneSeq, m int) (res int) {
for i := 0; i < 31; i++ {
a, b := (zeroSeq>>i)&1, (oneSeq>>i)&1
if a == 0 && b == 1 {
res += int(math.Pow(float64(2), float64(i)))
}
}
//=====================================
for res > m {
hPos := 30 // 找到 ans 最高位的 ‘1’
for res >> hPos == 0 {
hPos --
}
if (res & (1 << hPos)) > m { // 尝试将最高位清掉再比较
res = res & (^(1 << hPos))
} else { //依次尝试去掉尾部的1
for res > m {
lowPos := 0
for (res>>lowPos)&1 == 0 {
lowPos++
}
res = res & (^(1 << lowPos))
}
}
}
return
}

京公网安备 11010502036488号