Open In App

Print exchange order and swap count to make count of 1s same rowwise in Binary Matrix

Improve
Improve
Like Article
Like
Save
Share
Report

Given a n*m binary matrix, the task is to make an equal number of 1’s in each row using the operation as follows: Choose any two rows from (1 to n) and a column from (1 to m) and swap the elements present at these two positions. If it is possible to make equal ones in each row then return the number of steps required and the positions chosen(1-Based indexing) else return -1.

Examples:

Input: n = 3, m = 4, arr[] = {{1, 1, 1, 0}, {0, 0, 1, 0}, {1, 0, 0, 1}};
Output: 1
2 1 1 
Explanation: It’s enough to do a single operation: to swap the first element in the second and the first rows. The array will become {{0, 1, 1, 0}, {1, 0, 1, 0}, {1, 0, 0, 1}}, each row contains exactly two 1s.

Input: n = 2, m = 2, arr[] = {{0, 0}, {0, 1}}
Output: -1
Explanation: It is impossible to make equal ones in all the rows.

Approach: The above problem can be solved through the idea:

As we need to make the number of ones in each row of the given array the same, we should calculate the number of ones in the whole array. If the total number of ones in the array is divisible by n (number of rows) then it is possible to make equal ones otherwise it is impossible to make equal ones hence returning -1. If it is possible then count the number of ones in each row if it is greater than (number of ones/n) then reduce and perform the operation. Else if the number of ones is exactly equal to the (total ones/n) then do nothing.

Follow the below steps to implement the idea:

  • First, count the total number of ones as total_ones in the arr.
  • If total_ones is multiple of n then it is possible to make equal ones otherwise return -1.
  • Create a vector ans to store the row numbers and column numbers on which operations are performed.
  • Make two vectors iterate the first column to find which rows operation is needed. If the count of ones in any row is greater than total_ones/n then push it in the first vector if less than the push it into the second vector. After the complete iteration pushes the row numbers and column numbers in the ans.
  • For each column do the above operation.

Below is the implementation of the above approach.

C++14




// C++ implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate the number of
// steps and print the steps performed
void calculate(int n, int m, vector<vector<int> >& Arr)
{
    vector<int> sum(n, 0);
 
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
 
            // Count of ones in each row
            sum[i] += Arr[i][j];
        }
    }
 
    int total_ones = 0;
    for (int i = 0; i < n; ++i)
        total_ones += sum[i];
 
    // If total number of ones is not a
    // multiple of n then return -1
    if (total_ones % n) {
 
        cout << "-1\n";
        return;
    }
 
    total_ones /= n;
    vector<vector<int> > ans;
 
    // Check each row and count number of
    // ones and perform operation
    for (int j = 0; j < m; ++j) {
 
        // Create two vectors
        vector<int> V1, V2;
        for (int i = 0; i < n; ++i) {
            if (sum[i] > total_ones && Arr[i][j])
                V1.push_back(i);
            if (sum[i] < total_ones && !Arr[i][j])
                V2.push_back(i);
        }
        for (int i = 0; i < min(V2.size(), V1.size());
             ++i) {
            ++sum[V2[i]], --sum[V1[i]];
            ans.push_back({ V2[i], V1[i], j });
        }
    }
 
    // Print the steps required
    cout << ans.size() << endl;
 
    // Print on swapping done
    for (auto i : ans)
        cout << i[0] + 1 << " " << i[1] + 1 << " "
             << i[2] + 1 << " ";
}
 
// Driver code
int main()
{
    int n = 3, m = 4;
    vector<vector<int> > Arr = { { 1, 1, 1, 0 },
                                 { 0, 0, 1, 0 },
                                 { 1, 0, 0, 1 } };
 
    // Function call
    calculate(n, m, Arr);
 
    return 0;
}


Java




// Java implementation of the above approach
import java.io.*;
import java.util.*;
 
class GFG {
 
  // Function to calculate the number of
  // steps and print the steps performed
  static void calculate(int n, int m, int[][] Arr)
  {
 
    int[] sum = new int[n];
 
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < m; ++j) {
 
        // Count of ones in each row
        sum[i] += Arr[i][j];
      }
    }
 
    int total_ones = 0;
    for (int i = 0; i < n; ++i)
      total_ones += sum[i];
 
    // If total number of ones is not a
    // multiple of n then return -1
    if (total_ones % n != 0) {
      System.out.println("-1");
      return;
    }
 
    total_ones /= n;
    List<List<Integer> > ans = new ArrayList<>();
 
    // Check each row and count number of
    // ones and perform operation
    for (int j = 0; j < m; ++j) {
 
      // Create two lists
      List<Integer> V1 = new ArrayList<>();
      List<Integer> V2 = new ArrayList<>();
      for (int i = 0; i < n; ++i) {
        if (sum[i] > total_ones && Arr[i][j] == 1) {
          V1.add(i);
        }
        if (sum[i] < total_ones && Arr[i][j] == 0) {
          V2.add(i);
        }
      }
      for (int i = 0;
           i < Math.min(V2.size(), V1.size()); ++i) {
        ++sum[V2.get(i)];
        --sum[V1.get(i)];
        List<Integer> current = new ArrayList<>();
        current.add(V2.get(i));
        current.add(V1.get(i));
        current.add(j);
        ans.add(current);
      }
    }
 
    // Print the steps required
    System.out.println(ans.size());
 
    // Print on swapping done
    for (List<Integer> i : ans) {
      System.out.print((i.get(0) + 1) + " "
                       + (i.get(1) + 1) + " "
                       + (i.get(2) + 1) + " ");
    }
  }
 
  public static void main(String[] args)
  {
    int n = 3, m = 4;
    int[][] Arr = { { 1, 1, 1, 0 },
                   { 0, 0, 1, 0 },
                   { 1, 0, 0, 1 } };
 
    // Function call
    calculate(n, m, Arr);
  }
}
 
// This code is contributed by lokesh.


Python3




from typing import List, Tuple
 
def calculate(n: int, m: int, Arr: List[List[int]]) -> None:
    # Create a list to store the sum of ones in each row
    sum_ = [0] * n
 
    # Count the number of ones in each row
    for i in range(n):
        for j in range(m):
            sum_[i] += Arr[i][j]
 
    # Calculate the total number of ones in the matrix
    total_ones = sum(sum_)
 
    # If total number of ones is not a multiple of n then return -1
    if total_ones % n != 0:
        print("-1")
        return
 
    # Divide the total number of ones by n to get the ideal number of ones for each row
    total_ones = total_ones // n
 
    # Create a list to store the swaps
    ans = []
 
    # Check each row and count the number of ones and perform operation
    for j in range(m):
        # Create two lists to store the rows that have more than the ideal number of ones
        # and the rows that have less than the ideal number of ones
        V1, V2 = [], []
        for i in range(n):
            if sum_[i] > total_ones and Arr[i][j]:
                V1.append(i)
            if sum_[i] < total_ones and not Arr[i][j]:
                V2.append(i)
         
        # perform swap operation and update the ans list
        for i in range(min(len(V2), len(V1))):
            sum_[V2[i]] += 1
            sum_[V1[i]] -= 1
            ans.append((V2[i], V1[i], j))
 
    # Print the number of steps
    print(len(ans))
 
    # Print the steps
    for i in ans:
        print(i[0]+1, i[1]+1, i[2]+1)
 
# Driver code
n = 3
m = 4
Arr = [
    [1, 1, 1, 0],
    [0, 0, 1, 0],
    [1, 0, 0, 1]
]
calculate(n, m, Arr)
 
# This code is contributed by lokeshpotta20.


C#




// C# implementation of the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
  // Function to calculate the number of
  // steps and print the steps performed
  static void Calculate(int n, int m, int[, ] Arr)
  {
    int[] sum = new int[n];
 
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < m; ++j) {
 
        // Count of ones in each row
        sum[i] += Arr[i, j];
      }
    }
 
    int total_ones = 0;
    for (int i = 0; i < n; ++i)
      total_ones += sum[i];
 
    // If total number of ones is not a
    // multiple of n then return -1
    if (total_ones % n != 0) {
      Console.WriteLine("-1");
      return;
    }
 
    total_ones /= n;
    List<List<int> > ans = new List<List<int> >();
 
    // Check each row and count number of
    // ones and perform operation
    for (int j = 0; j < m; ++j) {
 
      // Create two lists
      List<int> V1 = new List<int>();
      List<int> V2 = new List<int>();
      for (int i = 0; i < n; ++i) {
        if (sum[i] > total_ones && Arr[i, j] == 1) {
          V1.Add(i);
        }
        if (sum[i] < total_ones && Arr[i, j] == 0) {
          V2.Add(i);
        }
      }
      for (int i = 0;
           i < Math.Min(V2.Count, V1.Count); ++i) {
        ++sum[V2[i]];
        --sum[V1[i]];
        List<int> current = new List<int>();
        current.Add(V2[i]);
        current.Add(V1[i]);
        current.Add(j);
        ans.Add(current);
      }
    }
 
    // Print the steps required
    Console.WriteLine(ans.Count);
 
    // Print on swapping done
    foreach(List<int> i in ans)
    {
      Console.Write((i[0] + 1) + " " + (i[1] + 1)
                    + " " + (i[2] + 1) + " ");
    }
  }
 
  static public void Main()
  {
 
    // Code
    int n = 3, m = 4;
    int[, ] Arr = { { 1, 1, 1, 0 },
                   { 0, 0, 1, 0 },
                   { 1, 0, 0, 1 } };
 
    // Function call
    Calculate(n, m, Arr);
  }
}
 
// This code is contributed by lokeshmvs21.


Javascript




// JavaScript implementation of the above approach
 
// Function to calculate the number of
// steps and print the steps performed
function calculate(n, m, Arr) {
    let sum = Array(n).fill(0);
 
    for (let i = 0; i < n; ++i) {
        for (let j = 0; j < m; ++j) {
 
            // Count of ones in each row
            sum[i] += Arr[i][j];
        }
    }
 
    let total_ones = 0;
    for (let i = 0; i < n; ++i)
        total_ones += sum[i];
 
    // If total number of ones is not a
    // multiple of n then return -1
    if (total_ones % n) {
 
        console.log("-1");
        return;
    }
 
    total_ones /= n;
    let ans = [];
 
    // Check each row and count number of
    // ones and perform operation
    for (let j = 0; j < m; ++j) {
 
        // Create two arrays
        let V1 = [], V2 = [];
        for (let i = 0; i < n; ++i) {
            if (sum[i] > total_ones && Arr[i][j])
                V1.push(i);
            if (sum[i] < total_ones && !Arr[i][j])
                V2.push(i);
        }
        for (let i = 0; i < Math.min(V2.length, V1.length); ++i) {
            ++sum[V2[i]], --sum[V1[i]];
            ans.push([V2[i], V1[i], j]);
        }
    }
 
    // Print the steps required
    console.log(ans.length);
 
    // Print on swapping done
    for (let i of ans)
        console.log((i[0] + 1) + " " + (i[1] + 1) + " " + (i[2] + 1));
}
 
// Driver code
let n = 3, m = 4;
let Arr = [
    [1, 1, 1, 0],
    [0, 0, 1, 0],
    [1, 0, 0, 1]
];
 
// Function call
calculate(n, m, Arr);


Output

1
2 1 1 

Time Complexity: O(N*M)
Auxiliary Space: O(2*N)



Last Updated : 06 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads