技巧:
在(特殊数)探测的结果下进行贪心找出最优解。(只关注数字二进制下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 }