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

📅  最后修改于: 2021-09-04 11:43:19             🧑  作者: Mango

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

例子

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

  • 在所需的矩阵中,从角开始的任何子矩阵必须使所有单元格的按位异或等于0
  • 还可以观察到,中最多应该存在两种类型的序列,即{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]和增量rowSumM [I] [0],colSumM [0] [i]和增量rowSwap1,如果M [i] [0]等于i%如果M[0][i]等于i%2则为2colSwap1
    2. 如果rowSum不等于N/2(N+1)/2 中的任何一个,则返回-1
    3. 如果colSum不等于N/2 或 (N+1)/2 中的任何一个,则返回-1
    4. 分配colSwap = N – colSwap如果, N%2colSwap%2都不等于 0 并且rowSwap = N – rowSwap如果N%2rowSwap%2都不等于 0。
    5. 分配colSwap等于colSwapN-colSwap 的最小值,并且rowSwap等于rowSwapN-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 )

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live