📌  相关文章
📜  使二进制矩阵的每对相邻单元格不同所需的最小行或列交换

📅  最后修改于: 2021-04-27 19:42:35             🧑  作者: Mango

给定尺寸为N x N的二进制矩阵M [] [] ,任务是通过交换最小数量的行或列,使给定矩阵的同一行或同一列中的每对相邻单元格区分开。

例子

方法:可以根据以下观察结果解决给定问题:

  • 在所需矩阵中,任何从角开始的子矩阵都必须具有等于0的所有像元的按位XOR。
  • 还可以观察到,在一行或一中最多应存在两种类型的序列,即{0,1,0,1}和{1,0,1,1}。因此,通过将序列的XOR值与1交换,可以从另一个序列生成一个序列。
  • 因此,通过仅根据所需格式制作第一和第一,所需的总交换量将最小化。

请按照以下步骤解决问题:

  1. 遍历矩阵M [] []并检查所有元素M [i] [0]M [0] [j]M [0] [0]M [i] [j]的按位异或1然后返回-1
  2. 0初始化变量rowSumcolSumrowSwapcolSwap
    1. [0,N-1]范围内遍历,如果M [i] [0]等于i%则将rowSum增大M [i] [0] ,将colSum增大M [0] [i] ,将rowSwap增大1。 2 ,如果M [0] [i]等于i%2 ,则colSwap减1
    2. 如果rowSum不等于N / 2(N + 1)/ 2,则返回-1
    3. 如果colSum不等于N / 2或(N + 1)/ 2,则返回-1
    4. 如果col% = N – colSwap,如果N%2colSwap%2都不等于0 rowSwap = N –如果N%2rowSwap%2都不等于0,则为rowSwap
    5. 分配colSwap等于最小colSwap和N- colSwap的,和rowSwap等于最小rowSwap和N- rowSwap的。
  3. 最后,将结果打印为(rowSum + colSum)/ 2

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to return number of moves
// to convert matrix into chessboard
int minSwaps(vector >& b)
{
    // Size of the matrix
    int n = b.size();
 
    // Traverse the matrix
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (b[0][0] ^ b[0][j] ^ b[i][0] ^ b[i][j])
                return -1;
        }
    }
 
    // Initialize rowSum to count 1s in row
    int rowSum = 0;
 
    // Initialize colSum to count 1s in column
    int colSum = 0;
 
    // To store no. of rows to be corrected
    int rowSwap = 0;
 
    // To store no. of columns to be corrected
    int colSwap = 0;
 
    // Traverse in the range [0, N-1]
    for (int i = 0; i < n; i++) {
        rowSum += b[i][0];
        colSum += b[0][i];
        rowSwap += b[i][0] == i % 2;
        colSwap += b[0][i] == i % 2;
    }
    // Check if rows is either N/2 or
    // (N+1)/2 and return -1
    if (rowSum != n / 2 && rowSum != (n + 1) / 2)
        return -1;
 
    // Check if rows is either N/2
    // or (N+1)/2  and return -1
    if (colSum != n / 2 && colSum != (n + 1) / 2)
        return -1;
 
    // Check if N is odd
    if (n % 2 == 1) {
 
        // Check if column required to be
        // corrected is odd and then
        // assign N-colSwap to colSwap
        if (colSwap % 2)
            colSwap = n - colSwap;
 
        // Check if rows required to
        // be corrected is odd and then
        // assign N-rowSwap to rowSwap
        if (rowSwap % 2)
            rowSwap = n - rowSwap;
    }
    else {
 
        // Take min of colSwap and N-colSwap
        colSwap = min(colSwap, n - colSwap);
 
        // Take min of rowSwap and N-rowSwap
        rowSwap = min(rowSwap, n - rowSwap);
    }
 
    // Finally return answer
    return (rowSwap + colSwap) / 2;
}
 
// Driver Code
int main()
{
 
    // Given matrix
    vector > M = { { 0, 1, 1, 0 },
                               { 0, 1, 1, 0 },
                               { 1, 0, 0, 1 },
                               { 1, 0, 0, 1 } };
 
    // Function Call
    int ans = minSwaps(M);
 
    // Print answer
    cout << ans;
}


Java
// Java program for the above approach
import java.io.*;
import java.util.*; 
class GFG
{
 
  // Function to return number of moves
  // to convert matrix into chessboard
  public static int minSwaps(int[][] b)
  {
 
    // Size of the matrix
    int n = b.length;
 
 
    // Traverse the matrix
    for (int i = 0; i < n; i++)
    {
      for (int j = 0; j < n; j++)
      {
 
        if ((b[0][0] ^ b[0][j] ^ b[i][0] ^ b[i][j]) == 1)
        {
          return -1;
        }
      }
    }
 
    // Initialize rowSum to count 1s in row
    int rowSum = 0;
 
    // Initialize colSum to count 1s in column
    int colSum = 0;
 
    // To store no. of rows to be corrected
    int rowSwap = 0;
 
    // To store no. of columns to be corrected
    int colSwap = 0;
 
    // Traverse in the range [0, N-1]
    for (int i = 0; i < n; i++)
    {
      rowSum += b[i][0];
      colSum += b[0][i];
      int cond1 = 0;
      int cond2 = 0;
      if(b[i][0] == i % 2)
        cond1 = 1;
      if(b[0][i] == i % 2)
        cond2 = 1;
      rowSwap += cond1;
      colSwap += cond2;
    }
 
    // Check if rows is either N/2 or
    // (N+1)/2 and return -1
    if (rowSum != n / 2 && rowSum != (n + 1) / 2)
      return -1;
 
    // Check if rows is either N/2
    // or (N+1)/2  and return -1
    if (colSum != n / 2 && colSum != (n + 1) / 2)
      return -1;
 
    // Check if N is odd
    if (n % 2 == 1)
    {
 
      // Check if column required to be
      // corrected is odd and then
      // assign N-colSwap to colSwap
      if ((colSwap % 2) == 1)
        colSwap = n - colSwap;
 
      // Check if rows required to
      // be corrected is odd and then
      // assign N-rowSwap to rowSwap
      if ((rowSwap % 2) == 1)
        rowSwap = n - rowSwap;
    }
    else
    {
 
      // Take min of colSwap and N-colSwap
      colSwap = Math.min(colSwap, n - colSwap);
 
      // Take min of rowSwap and N-rowSwap
      rowSwap = Math.min(rowSwap, n - rowSwap);
    }
 
    // Finally return answer
    return (rowSwap + colSwap) / 2;
  }
 
  // Driver Code
  public static void main (String[] args)
  {
 
    // Given matrix
    int[][] M = { { 0, 1, 1, 0 },
                 { 0, 1, 1, 0 },
                 { 1, 0, 0, 1 },
                 { 1, 0, 0, 1 } };
 
    // Function Call
    int ans = minSwaps(M);
 
    // Print answer
    System.out.println(ans);
  }
}
 
// This code is contributed by rohitsingh07052


Python3
# Python3 program for the above approach
 
# Function to return number of moves
# to convert matrix into chessboard
def minSwaps(b):
 
    # Size of the matrix
    n = len(b)
 
    # Traverse the matrix
    for i in range(n):
        for j in range(n):
            if (b[0][0] ^ b[0][j] ^
                b[i][0] ^ b[i][j]):
                return -1
 
    # Initialize rowSum to count 1s in row
    rowSum = 0
 
    # Initialize colSum to count 1s in column
    colSum = 0
 
    # To store no. of rows to be corrected
    rowSwap = 0
 
    # To store no. of columns to be corrected
    colSwap = 0
 
    # Traverse in the range [0, N-1]
    for i in range(n):
        rowSum += b[i][0]
        colSum += b[0][i]
        rowSwap += b[i][0] == i % 2
        colSwap += b[0][i] == i % 2
 
    # Check if rows is either N/2 or
    # (N+1)/2 and return -1
    if (rowSum != n // 2 and
        rowSum != (n + 1) // 2):
        return -1
 
    # Check if rows is either N/2
    # or (N+1)/2  and return -1
    if (colSum != n // 2 and
        colSum != (n + 1) // 2):
        return -1
 
    # Check if N is odd
    if (n % 2 == 1):
 
        # Check if column required to be
        # corrected is odd and then
        # assign N-colSwap to colSwap
        if (colSwap % 2):
            colSwap = n - colSwap
 
        # Check if rows required to
        # be corrected is odd and then
        # assign N-rowSwap to rowSwap
        if (rowSwap % 2):
            rowSwap = n - rowSwap
 
    else:
 
        # Take min of colSwap and N-colSwap
        colSwap = min(colSwap, n - colSwap)
 
        # Take min of rowSwap and N-rowSwap
        rowSwap = min(rowSwap, n - rowSwap)
 
    # Finally return answer
    return (rowSwap + colSwap) // 2
 
# Driver Code
if __name__ == "__main__":
 
    # Given matrix
    M = [ [ 0, 1, 1, 0 ],
          [ 0, 1, 1, 0 ],
          [ 1, 0, 0, 1 ],
          [ 1, 0, 0, 1 ] ]
 
    # Function Call
    ans = minSwaps(M)
 
    # Print answer
    print(ans)
 
# This code is contributed by chitranayal


C#
// C# program for the above approach
using System;
class GFG
{
 
  // Function to return number of moves
  // to convert matrix into chessboard
  public static int minSwaps(int[,] b)
  {
 
    // Size of the matrix
    int n = b.GetLength(0);
 
 
    // Traverse the matrix
    for (int i = 0; i < n; i++)
    {
      for (int j = 0; j < n; j++)
      {
 
        if ((b[0, 0] ^ b[0, j] ^ b[i, 0] ^ b[i, j]) == 1)
        {
          return -1;
        }
      }
    }
 
    // Initialize rowSum to count 1s in row
    int rowSum = 0;
 
    // Initialize colSum to count 1s in column
    int colSum = 0;
 
    // To store no. of rows to be corrected
    int rowSwap = 0;
 
    // To store no. of columns to be corrected
    int colSwap = 0;
 
    // Traverse in the range [0, N-1]
    for (int i = 0; i < n; i++)
    {
      rowSum += b[i, 0];
      colSum += b[0, i];
      int cond1 = 0;
      int cond2 = 0;
      if(b[i, 0] == i % 2)
        cond1 = 1;
      if(b[0, i] == i % 2)
        cond2 = 1;
      rowSwap += cond1;
      colSwap += cond2;
    }
 
    // Check if rows is either N/2 or
    // (N+1)/2 and return -1
    if (rowSum != n / 2 && rowSum != (n + 1) / 2)
      return -1;
 
    // Check if rows is either N/2
    // or (N+1)/2  and return -1
    if (colSum != n / 2 && colSum != (n + 1) / 2)
      return -1;
 
    // Check if N is odd
    if (n % 2 == 1)
    {
 
      // Check if column required to be
      // corrected is odd and then
      // assign N-colSwap to colSwap
      if ((colSwap % 2) == 1)
        colSwap = n - colSwap;
 
      // Check if rows required to
      // be corrected is odd and then
      // assign N-rowSwap to rowSwap
      if ((rowSwap % 2) == 1)
        rowSwap = n - rowSwap;
    }
    else
    {
 
      // Take min of colSwap and N-colSwap
      colSwap = Math.Min(colSwap, n - colSwap);
 
      // Take min of rowSwap and N-rowSwap
      rowSwap = Math.Min(rowSwap, n - rowSwap);
    }
 
    // Finally return answer
    return (rowSwap + colSwap) / 2;
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
 
    // Given matrix
    int[,] M = { { 0, 1, 1, 0 },
                 { 0, 1, 1, 0 },
                 { 1, 0, 0, 1 },
                 { 1, 0, 0, 1 } };
 
    // Function Call
    int ans = minSwaps(M);
 
    // Print answer
    Console.WriteLine(ans);
  }
}
 
// This code is contributed by gauravrajput1


Javascript


输出:
2

时间复杂度: O(N 2 )
辅助空间: O(N 2 )