位图(位集),0b 和 C# Convert.ToInt32("字符串", 2) 表示二进制数字,求解《782. 变为棋盘》
一个 n x n 的二维网络 board 仅由 0 和 1 组成 。每次移动,你能任意交换两列或是两行的位置。
返回 将这个矩阵变为 “棋盘” 所需的最小移动次数 。如果不存在可行的变换,输出 -1。
“棋盘” 是指任意一格的上下左右四个方向的值均与本身不同的矩阵。
示例 1:
输入: board = [[0,1,1,0],[0,1,1,0],[1,0,0,1],[1,0,0,1]]
输出: 2
解释:一种可行的变换方式如下,从左到右:
第一次移动交换了第一列和第二列。
第二次移动交换了第二行和第三行。
示例 2:
输入: board = [[0, 1], [1, 0]] 输出: 0 解释: 注意左上角的格值为0时也是合法的棋盘,也是合法的棋盘. 示例 3:
输入: board = [[1, 0], [1, 0]] 输出: -1 解释: 任意的变换都不能使这个输入变为合法的棋盘。
var movesToChessboard = function(board) {
const n = board.length
let firstRow = 0, firstCol = 0, firstRowCnt = 1, firstColCnt = 1
for (let i = 0; i < n; i++) {
firstRow |= board[0][i] << i
firstCol |= board[i][0] << i
}
const firstRowReverse = ((1 << n) - 1) ^ firstRow, firstColReverse = ((1 << n) - 1) ^ firstCol
for (let i = 1; i < n; i++) {
let row = 0, col = 0
for (let j = 0; j < n; j++) {
row |= board[i][j] << j
col |= board[j][i] << j
}
if (row !== firstRow && row !== firstRowReverse) return -1
if (row === firstRow) firstRowCnt++
if (col !== firstCol && col !== firstColReverse) return -1
if (col === firstCol) firstColCnt++
}
if (Math.abs((firstRowCnt << 1) - n) > 1 || Math.abs((firstColCnt << 1) - n) > 1) return -1
return count(firstRow, n) + count(firstCol, n)
};
const count = (num, n) => {
const b1 = 0b10101010101010101010101010101010, b2 = 0b01010101010101010101010101010101, oneNum = countOne(num)
if (n & 1) {
if (oneNum === n >> 1) return oneNum - countOne(num & b1)
return oneNum - countOne(num & b2)
}
return oneNum - Math.max(countOne(num & b1), countOne(num & b2))
}
const countOne = n => {
let cnt = 0
while (n) {
n &= n - 1
cnt++
}
return cnt
}
function movesToChessboard(board: number[][]): number {
const n = board.length
let firstRow = 0, firstCol = 0, firstRowCnt = 1, fristColCnt = 1
for (let i = 0; i < n; i++) {
firstRow |= board[0][i] << i
firstCol |= board[i][0] << i
}
const firstRowReverse = ((1 << n) - 1) ^ firstRow, firstColReverse = ((1 << n) - 1) ^ firstCol
for (let i = 1; i < n; i++) {
let row = 0, col = 0
for (let j = 0; j < n; j++) {
row |= board[i][j] << j
col |= board[j][i] << j
}
if (row === firstRow) firstRowCnt++
else if (row !== firstRowReverse) return -1
if (col === firstCol) fristColCnt++
else if (col !== firstColReverse) return -1
}
if (Math.abs(firstRowCnt * 2 - n) > 1 || Math.abs(fristColCnt * 2 - n) > 1) return -1
return count(firstRow, n) + count(firstCol, n)
};
const count = (num: number, n: number): number => {
const b0 = 0b10101010101010101010101010101010, b1 = 0b01010101010101010101010101010101, oneCnt = count1(num)
if (n & 1) {
if (oneCnt === n >> 1) return oneCnt - count1(num & b0)
return oneCnt - count1(num & b1)
}
return oneCnt - Math.max(count1(num & b0), count1(num & b1))
}
const count1 = (n: number): number => {
let r = 0
while (n) {
n &= n - 1
r++
}
return r
}
class Solution {
function movesToChessboard($board) {
$n = count($board);
$firstRow = 0;
$firstCol = 0;
$firstRowCnt = 1;
$firstColCnt = 1;
for ($i = 0; $i < $n; $i++) {
$firstRow |= $board[0][$i] << $i;
$firstCol |= $board[$i][0] << $i;
}
$firstRowReverse = ((1 << $n) - 1) ^ $firstRow;
$firstColReverse = ((1 << $n) - 1) ^ $firstCol;
for ($i = 1; $i < $n; $i++) {
$row = 0;
$col = 0;
for ($j = 0; $j < $n; $j++) {
$row |= $board[$i][$j] << $j;
$col |= $board[$j][$i] << $j;
}
if ($row === $firstRow) $firstRowCnt++;
elseif ($row !== $firstRowReverse) return -1;
if ($col === $firstCol) $firstColCnt++;
elseif ($col !== $firstColReverse) return -1;
}
if (abs($firstRowCnt * 2 - $n) > 1 || abs($firstColCnt * 2 - $n) > 1) return -1;
return $this->count($firstRow, $n) + $this->count($firstCol, $n);
}
function count($num, $n) {
$b0 = 0b10101010101010101010101010101010;
$b1 = 0b01010101010101010101010101010101;
$oneCnt = $this->count1($num);
if ($n & 1) {
if ($oneCnt === $n >> 1) return $oneCnt - $this->count1($num & $b0);
return $oneCnt - $this->count1($num & $b1);
}
return $oneCnt - max($this->count1($num & $b0), $this->count1($num & $b1));
}
function count1($n) {
$r = 0;
while ($n) {
$n &= $n - 1;
$r++;
}
return $r;
}
}
func movesToChessboard(board [][]int) int {
n, firstRow, firstCol, firstRowCnt, firstColCnt := len(board), 0, 0, 1, 1
for i := 0; i < n; i++ {
firstRow |= board[0][i] << i
firstCol |= board[i][0] << i
}
firstRowReverse, firstColReverse := (1 << n - 1) ^ firstRow, (1 << n - 1) ^ firstCol
for i := 1; i < n; i++ {
row, col := 0, 0
for j := 0; j < n; j++ {
row |= board[i][j] << j
col |= board[j][i] << j
}
if row == firstRow {
firstRowCnt++
} else if row != firstRowReverse {
return -1
}
if col == firstCol {
firstColCnt++
} else if col != firstColReverse {
return -1
}
}
if math.Abs(float64(firstRowCnt * 2 - n)) > 1 || math.Abs(float64(firstColCnt * 2 - n)) > 1 {
return -1
}
return count(firstRow, n) + count(firstCol, n)
}
func count(num int, n int) int {
b0, b1, oneCnt := 0b10101010101010101010101010101010, 0b01010101010101010101010101010101, count1(num)
if n & 1 == 1 {
if oneCnt == n >> 1 {
return oneCnt - count1(num & b0)
}
return oneCnt - count1(num & b1)
}
return oneCnt - int(math.Max(float64(count1(num & b0)), float64(count1(num & b1))))
}
func count1(n int) int {
r := 0
for n > 0 {
n &= n - 1
r++
}
return r
}
class Solution {
public int movesToChessboard(int[][] board) {
int n = board.length, firstRow = 0, firstCol = 0, firstRowCnt = 1, firstColCnt = 1;
for (int i = 0; i < n; i++) {
firstRow |= board[0][i] << i;
firstCol |= board[i][0] << i;
}
int firstRowReverse = ((1 << n) - 1) ^ firstRow, firstColReverse = ((1 << n) - 1) ^ firstCol;
for (int i = 1; i < n; i++) {
int row = 0, col = 0;
for (int j = 0; j < n; j++) {
row |= board[i][j] << j;
col |= board[j][i] << j;
}
if (row == firstRow) firstRowCnt++;
else if (row != firstRowReverse) return -1;
if (col == firstCol) firstColCnt++;
else if (col != firstColReverse) return -1;
}
if (Math.abs(firstRowCnt * 2 - n) > 1 || Math.abs(firstColCnt * 2 - n) > 1) return -1;
return count(firstRow, n) + count(firstCol, n);
}
private int count(int num, int n) {
int b0 = 0b10101010101010101010101010101010, b1 = 0b01010101010101010101010101010101, oneCnt = count1(num);
if ((n & 1) == 1) { // java 和 c # 不能省略 ()
if (oneCnt == n >> 1) return oneCnt - count1(num & b0);
return oneCnt - count1(num & b1);
}
return oneCnt - Math.max(count1(num & b0), count1(num & b1));
}
private int count1(int n) {
int r = 0;
while (n > 0) {
n &= n - 1;
r++;
}
return r;
}
}
public class Solution { // Convert.ToInt32("", 2)
public int MovesToChessboard(int[][] board) {
int n = board.Length, firstRow = 0, firstCol = 0, firstRowCnt = 1, firstColCnt = 1;
for (int i = 0; i < n; i++) {
firstRow |= board[0][i] << i;
firstCol |= board[i][0] << i;
}
int firstRowReverse = ((1 << n) - 1) ^ firstRow, firstColReverse = ((1 << n) - 1) ^ firstCol;
for (int i = 1; i < n; i++) {
int row = 0, col = 0;
for (int j = 0; j < n; j++) {
row |= board[i][j] << j;
col |= board[j][i] << j;
}
if (row == firstRow) firstRowCnt++;
else if (row != firstRowReverse) return -1;
if (col == firstCol) firstColCnt++;
else if (col != firstColReverse) return -1;
}
if (Math.Abs(firstRowCnt * 2 - n) > 1 || Math.Abs(firstColCnt * 2 - n) > 1) return -1;
return Count(firstRow, n) + Count(firstCol, n);
}
private int Count(int num, int n) {
int b0 = Convert.ToInt32("10101010101010101010101010101010", 2), b1 = Convert.ToInt32("01010101010101010101010101010101", 2), oneCnt = Count1(num);
if ((n & 1) == 1) { // java 和 c # 不能省略 ()
if (oneCnt == n >> 1) return oneCnt - Count1(num & b0);
return oneCnt - Count1(num & b1);
}
return oneCnt - Math.Max(Count1(num & b0), Count1(num & b1));
}
private int Count1(int n) {
int r = 0;
while (n > 0) {
n &= n - 1;
r++;
}
return r;
}
}
public class Solution { // int -> uint
public int MovesToChessboard(int[][] board) {
int n = board.Length, firstRow = 0, firstCol = 0, firstRowCnt = 1, firstColCnt = 1;
for (int i = 0; i < n; i++) {
firstRow |= board[0][i] << i;
firstCol |= board[i][0] << i;
}
int firstRowReverse = ((1 << n) - 1) ^ firstRow, firstColReverse = ((1 << n) - 1) ^ firstCol;
for (int i = 1; i < n; i++) {
int row = 0, col = 0;
for (int j = 0; j < n; j++) {
row |= board[i][j] << j;
col |= board[j][i] << j;
}
if (row == firstRow) firstRowCnt++;
else if (row != firstRowReverse) return -1;
if (col == firstCol) firstColCnt++;
else if (col != firstColReverse) return -1;
}
if (Math.Abs(firstRowCnt * 2 - n) > 1 || Math.Abs(firstColCnt * 2 - n) > 1) return -1;
return (int)(Count((uint)firstRow, n) + Count((uint)firstCol, n));
}
private uint Count(uint num, int n) {
uint b0 = 2863311530, b1 = 1431655765;
uint oneCnt = Count1(num);
if ((n & 1) == 1) { // java 和 c # 不能省略 ()
if (oneCnt == n >> 1) return oneCnt - Count1(num & b0);
return oneCnt - Count1(num & b1);
}
return oneCnt - Math.Max(Count1(num & b0), Count1(num & b1));
}
private uint Count1(uint n) {
uint r = 0;
while (n > 0) {
n &= n - 1;
r++;
}
return r;
}
}
#define MAX(a, b) (a > b ? a : b) // 不省略括号,避免出现 1 - MAX(a, b) = 1 的问题
int count1(int n){
int r = 0;
while (n > 0) {
n &= n - 1;
r++;
}
return r;
}
int count(int num, int n){
int b0 = 0b10101010101010101010101010101010, b1 = 0b01010101010101010101010101010101, oneCnt = count1(num);
if (n & 1 == 1) {
if (oneCnt == n >> 1) return oneCnt - count1(num & b0);
return oneCnt - count1(num & b1);
}
return oneCnt - MAX(count1(num & b0), count1(num & b1));
}
int movesToChessboard(int** board, int boardSize, int* boardColSize){
int firstRow = 0, firstCol = 0, firstRowCnt = 1, fristColCnt = 1;
for (int i = 0; i < boardSize; i++) {
firstRow |= board[0][i] << i;
firstCol |= board[i][0] << i;
}
int firstRowReverse = ((1 << boardSize) - 1) ^ firstRow, firstColReverse = ((1 << boardSize) - 1) ^ firstCol;
for (int i = 1; i < boardSize; i++) {
int row = 0, col = 0;
for (int j = 0; j < boardSize; j++) {
row |= board[i][j] << j;
col |= board[j][i] << j;
}
if (row == firstRow) firstRowCnt++;
else if (row != firstRowReverse) return -1;
if (col == firstCol) fristColCnt++;
else if (col != firstColReverse) return -1;
}
if (abs(firstRowCnt * 2 - boardSize) > 1 || abs(fristColCnt * 2 - boardSize) > 1) return -1;
return count(firstRow, boardSize) + count(firstCol, boardSize);
}
class Solution {
private:
int count1(int n) {
int r = 0;
while (n) {
n &= n - 1;
r++;
}
return r;
}
int count(int num, int n) {
int b0 = 0b10101010101010101010101010101010, b1 = 0b01010101010101010101010101010101, oneCnt = count1(num);
if (n & 1 == 1) {
if (oneCnt == n >> 1) return oneCnt - count1(num & b0);
return oneCnt - count1(num & b1);
}
return oneCnt - max(count1(num & b0), count1(num & b1));
}
public:
int movesToChessboard(vector<vector<int>>& board) {
int n = board.size(), firstRow = 0, firstCol = 0, firstRowCnt = 1, firstColCnt = 1;
for (int i = 0; i < n; i++) {
firstRow |= board[0][i] << i;
firstCol |= board[i][0] << i;
}
int firstRowReverse = ((1 << n) - 1) ^ firstRow, firstColReverse = ((1 << n) - 1) ^ firstCol;
for (int i = 1; i < n; i++) {
int row = 0, col = 0;
for (int j = 0; j < n; j++) {
row |= board[i][j] << j;
col |= board[j][i] << j;
}
if (row == firstRow) firstRowCnt++;
else if (row != firstRowReverse) return -1;
if (col == firstCol) firstColCnt++;
else if (col != firstColReverse) return -1;
}
if (abs(firstRowCnt * 2 - n) > 1 || abs(firstColCnt * 2 - n) > 1) return -1;
return count(firstRow, n) + count(firstCol, n);
}
};
class Solution:
def movesToChessboard(self, board: List[List[int]]) -> int:
n, firstRow, firstCol, firstRowCnt, firstColCnt = len(board), 0, 0, 1, 1
for i in range(0, n):
firstRow |= board[0][i] << i
firstCol |= board[i][0] << i
firstRowReverse, firstColReverse = ((1 << n) - 1) ^ firstRow, ((1 << n) - 1) ^ firstCol
for i in range(1, n):
row, col = 0, 0
for j in range(0, n):
row |= board[i][j] << j
col |= board[j][i] << j
if row == firstRow: firstRowCnt += 1
elif row != firstRowReverse: return -1
if col == firstCol: firstColCnt += 1
elif col != firstColReverse: return -1
if abs(firstRowCnt * 2 - n) > 1 or abs(firstColCnt * 2 - n) > 1: return -1
return self.count(firstRow, n) + self.count(firstCol, n)
def count(self, num: int, n: int) -> int:
b0, b1, oneCnt = 0b10101010101010101010101010101010, 0b01010101010101010101010101010101, self.count1(num)
if n & 1:
if oneCnt == n >> 1: return oneCnt - self.count1(num & b0)
return oneCnt - self.count1(num & b1)
return oneCnt - max(self.count1(num & b0), self.count1(num & b1))
def count1(self, n: int) -> int:
r = 0
while n:
n &= n - 1
r += 1
return r