返回介绍

solution / 0700-0799 / 0782.Transform to Chessboard / README_EN

发布于 2024-06-17 01:03:34 字数 8870 浏览 0 评论 0 收藏 0

782. Transform to Chessboard

中文文档

Description

You are given an n x n binary grid board. In each move, you can swap any two rows with each other, or any two columns with each other.

Return _the minimum number of moves to transform the board into a chessboard board_. If the task is impossible, return -1.

A chessboard board is a board where no 0's and no 1's are 4-directionally adjacent.

 

Example 1:

Input: board = [[0,1,1,0],[0,1,1,0],[1,0,0,1],[1,0,0,1]]
Output: 2
Explanation: One potential sequence of moves is shown.
The first move swaps the first and second column.
The second move swaps the second and third row.

Example 2:

Input: board = [[0,1],[1,0]]
Output: 0
Explanation: Also note that the board with 0 in the top left corner, is also a valid chessboard.

Example 3:

Input: board = [[1,0],[1,0]]
Output: -1
Explanation: No matter what sequence of moves you make, you cannot end with a valid chessboard.

 

Constraints:

  • n == board.length
  • n == board[i].length
  • 2 <= n <= 30
  • board[i][j] is either 0 or 1.

Solutions

Solution 1

class Solution:
  def movesToChessboard(self, board: List[List[int]]) -> int:
    def f(mask, cnt):
      ones = mask.bit_count()
      if n & 1:
        if abs(n - 2 * ones) != 1 or abs(n - 2 * cnt) != 1:
          return -1
        if ones == n // 2:
          return n // 2 - (mask & 0xAAAAAAAA).bit_count()
        return (n + 1) // 2 - (mask & 0x55555555).bit_count()
      else:
        if ones != n // 2 or cnt != n // 2:
          return -1
        cnt0 = n // 2 - (mask & 0xAAAAAAAA).bit_count()
        cnt1 = n // 2 - (mask & 0x55555555).bit_count()
        return min(cnt0, cnt1)

    n = len(board)
    mask = (1 << n) - 1
    rowMask = colMask = 0
    for i in range(n):
      rowMask |= board[0][i] << i
      colMask |= board[i][0] << i
    revRowMask = mask ^ rowMask
    revColMask = mask ^ colMask
    sameRow = sameCol = 0
    for i in range(n):
      curRowMask = curColMask = 0
      for j in range(n):
        curRowMask |= board[i][j] << j
        curColMask |= board[j][i] << j
      if curRowMask not in (rowMask, revRowMask) or curColMask not in (
        colMask,
        revColMask,
      ):
        return -1
      sameRow += curRowMask == rowMask
      sameCol += curColMask == colMask
    t1 = f(rowMask, sameRow)
    t2 = f(colMask, sameCol)
    return -1 if t1 == -1 or t2 == -1 else t1 + t2
class Solution {
  private int n;

  public int movesToChessboard(int[][] board) {
    n = board.length;
    int mask = (1 << n) - 1;
    int rowMask = 0, colMask = 0;
    for (int i = 0; i < n; ++i) {
      rowMask |= board[0][i] << i;
      colMask |= board[i][0] << i;
    }
    int revRowMask = mask ^ rowMask;
    int revColMask = mask ^ colMask;
    int sameRow = 0, sameCol = 0;
    for (int i = 0; i < n; ++i) {
      int curRowMask = 0, curColMask = 0;
      for (int j = 0; j < n; ++j) {
        curRowMask |= board[i][j] << j;
        curColMask |= board[j][i] << j;
      }
      if (curRowMask != rowMask && curRowMask != revRowMask) {
        return -1;
      }
      if (curColMask != colMask && curColMask != revColMask) {
        return -1;
      }
      sameRow += curRowMask == rowMask ? 1 : 0;
      sameCol += curColMask == colMask ? 1 : 0;
    }
    int t1 = f(rowMask, sameRow);
    int t2 = f(colMask, sameCol);
    return t1 == -1 || t2 == -1 ? -1 : t1 + t2;
  }

  private int f(int mask, int cnt) {
    int ones = Integer.bitCount(mask);
    if (n % 2 == 1) {
      if (Math.abs(n - ones * 2) != 1 || Math.abs(n - cnt * 2) != 1) {
        return -1;
      }
      if (ones == n / 2) {
        return n / 2 - Integer.bitCount(mask & 0xAAAAAAAA);
      }
      return (n / 2 + 1) - Integer.bitCount(mask & 0x55555555);
    } else {
      if (ones != n / 2 || cnt != n / 2) {
        return -1;
      }
      int cnt0 = n / 2 - Integer.bitCount(mask & 0xAAAAAAAA);
      int cnt1 = n / 2 - Integer.bitCount(mask & 0x55555555);
      return Math.min(cnt0, cnt1);
    }
  }
}
class Solution {
public:
  int n;
  int movesToChessboard(vector<vector<int>>& board) {
    n = board.size();
    int mask = (1 << n) - 1;
    int rowMask = 0, colMask = 0;
    for (int i = 0; i < n; ++i) {
      rowMask |= board[0][i] << i;
      colMask |= board[i][0] << i;
    }
    int revRowMask = mask ^ rowMask;
    int revColMask = mask ^ colMask;
    int sameRow = 0, sameCol = 0;
    for (int i = 0; i < n; ++i) {
      int curRowMask = 0, curColMask = 0;
      for (int j = 0; j < n; ++j) {
        curRowMask |= board[i][j] << j;
        curColMask |= board[j][i] << j;
      }
      if (curRowMask != rowMask && curRowMask != revRowMask) return -1;
      if (curColMask != colMask && curColMask != revColMask) return -1;
      sameRow += curRowMask == rowMask;
      sameCol += curColMask == colMask;
    }
    int t1 = f(rowMask, sameRow);
    int t2 = f(colMask, sameCol);
    return t1 == -1 || t2 == -1 ? -1 : t1 + t2;
  }

  int f(int mask, int cnt) {
    int ones = __builtin_popcount(mask);
    if (n & 1) {
      if (abs(n - ones * 2) != 1 || abs(n - cnt * 2) != 1) return -1;
      if (ones == n / 2) return n / 2 - __builtin_popcount(mask & 0xAAAAAAAA);
      return (n + 1) / 2 - __builtin_popcount(mask & 0x55555555);
    } else {
      if (ones != n / 2 || cnt != n / 2) return -1;
      int cnt0 = (n / 2 - __builtin_popcount(mask & 0xAAAAAAAA));
      int cnt1 = (n / 2 - __builtin_popcount(mask & 0x55555555));
      return min(cnt0, cnt1);
    }
  }
};
func movesToChessboard(board [][]int) int {
  n := len(board)
  mask := (1 << n) - 1
  rowMask, colMask := 0, 0
  for i := 0; i < n; i++ {
    rowMask |= board[0][i] << i
    colMask |= board[i][0] << i
  }
  revRowMask := mask ^ rowMask
  revColMask := mask ^ colMask
  sameRow, sameCol := 0, 0
  for i := 0; i < n; i++ {
    curRowMask, curColMask := 0, 0
    for j := 0; j < n; j++ {
      curRowMask |= board[i][j] << j
      curColMask |= board[j][i] << j
    }
    if curRowMask != rowMask && curRowMask != revRowMask {
      return -1
    }
    if curColMask != colMask && curColMask != revColMask {
      return -1
    }
    if curRowMask == rowMask {
      sameRow++
    }
    if curColMask == colMask {
      sameCol++
    }
  }
  f := func(mask, cnt int) int {
    ones := bits.OnesCount(uint(mask))
    if n%2 == 1 {
      if abs(n-ones*2) != 1 || abs(n-cnt*2) != 1 {
        return -1
      }
      if ones == n/2 {
        return n/2 - bits.OnesCount(uint(mask&0xAAAAAAAA))
      }
      return (n+1)/2 - bits.OnesCount(uint(mask&0x55555555))
    } else {
      if ones != n/2 || cnt != n/2 {
        return -1
      }
      cnt0 := n/2 - bits.OnesCount(uint(mask&0xAAAAAAAA))
      cnt1 := n/2 - bits.OnesCount(uint(mask&0x55555555))
      return min(cnt0, cnt1)
    }
  }
  t1 := f(rowMask, sameRow)
  t2 := f(colMask, sameCol)
  if t1 == -1 || t2 == -1 {
    return -1
  }
  return t1 + t2
}

func abs(x int) int {
  if x < 0 {
    return -x
  }
  return x
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文