Skip to content
Related Articles

Related Articles

Sum of numbers obtained by the count of set and non-set bits in diagonal matrix elements
  • Last Updated : 04 Mar, 2021

Given a square matrix mat[][] of dimension N*N, convert the elements present in both the diagonals to their respective binary representations and perform the following operations:

  • For every position of bits, count the number of set bits and non-set bits in those binary representations.
  • If count of set bits exceeds that of non-set bits, place 0 at that position for a new number. Otherwise, place 1 at that position.
  • Finally, print the sum of the two generated numbers.

Examples:

Input: mat[][] = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Output: 8
Explanation:
For the primary diagonal, the binary representation of each element is:
1 = (0001)2
5 = (0101)2
9 = (1001)2
At bit position 0, number of set bits(=3)>number of non-set bits(=0)
At bit position 1, number of set bits(=0)<number of non-set bits(=3)
At bit position 2, number of set bits(=1)<number of non-set bits(=2)
At bit position 3, number of set bits(=1)<number of non-set bits(=2)
Therefore, after processing the primary diagonal, the number generated is (0001)2 = 1.
For the secondary diagonal, the binary representation of each element is:
3 = (011)2
5 = (101)2
7 = (111)2
At bit position 0, number of set bits(=3)>number of non-set bits(=0)
At bit position 1, number of set bits(=2)>number of non-set bits(=1)
At bit position 2, number of set bits(=2)>number of non-set bits(=1)
Therefore, after processing the primary diagonal, the number generated is (111)2 = 7.
Hence, the required sum = 1 + 7 = 8. 

Input: mat[][] = [[2, 3], [3, 9]]
Output: 3

Naive Approach: The simplest approach is to traverse the matrix and store the primary diagonal elements in an array and the secondary diagonal elements in another array. Then find the sum of the numbers generated by iterating over the set bits of the elements in both the arrays. 
Time Complexity: O(N2)
Auxiliary Space: O(1) 



Efficient Approach: The above approach can be optimized by finding the diagonal elements using a single loop. Follow the steps below to solve the problem:

  • For Principal Diagonal elements: Iterate a loop until N, where N is the number of columns, and store mat[i][i] where i is the index variable.
  • For Secondary Diagonal elements: Iterate a loop until N, where N is the number of columns and store mat[i][k], where i is the index variable and K = N – 1. Decrease K until i < N.

For finding the numbers for each set of diagonal elements, perform the following steps:

  • Initialize a variable, say ans as 0, to store the resultant number.
  • Iterate over the range [0, 31] using variable i and perform the following:
    • Initialize S and NS as 0, to store the number of set and non-set bits respectively at position i.
    • Traverse the diagonal elements using variable j and if arr[j] is set at position i, increment S by 1, else increment NS by 1.
    • If the value of S is greater than NS, set the bit at position i of ans.
  • After completing the above steps, the value of ans is the number generated for each set of diagonal elements.
  • Repeat the above steps for the other sets of diagonal elements, and print the sum of the two numbers generated.

Below is the implementation of the above approach:

C++




// CPP program for the above approach
#include<bits/stdc++.h>
using namespace std;
 
// Functino to find the number after
// processing the diagonal elements
int processDiagonal(vector<int>arr)
{
   
  // Store the required number
  int ans = 0;
   
  int getBit = 1;
   
  // Checking for each position
  for (int i = 0; i < 32; i++)
  {
 
   // Store the number of set bits
    // & non-set bits at position i
    int S = 0;
    int NS = 0;
     
    // Traverse the diagonal elements
    for(auto j: arr)
    {
       
         // Update count of S if current
      // element is set at position i
      if (getBit&j)
        S += 1;
         
      // Else update NS
      else
        NS += 1;
    }
    // If number of set bits is >
    // number of non-set bits, add
    // set bits value to the ans
    if(S > NS)
      ans += pow(2,i);
    getBit <<= 1;
 
  }
     
  // Return the answer
  return ans;
}
 
// Function to find the sum of the
// numbers generated after processing
// both the diagonals of the matrix
int findSum(vector<vector<int>>mat)
{
     
  int i = 0;
  int j = 0;
   
  // Store the primary diagonal elements
  vector<int> priDiag;
   
  while(i<mat.size()){
    priDiag.push_back(mat[i][j]);
    i += 1;
    j += 1;
  }
     
  i = 0;
  j = mat.size()-1;
   
  // Store the secondary diagonal elements
  vector<int> secDiag;
  while(i<mat.size()){
    secDiag.push_back(mat[i][j]);
    i += 1;
    j -= 1;
  }
     
  // Function Call to get the required
  // numbers and return their sum
  return processDiagonal(priDiag) + processDiagonal(secDiag);
 
}
 
// Driver Code
int main(){
vector<vector<int>>mat{{1, 2, 3},{4, 5, 6},{7, 8, 9}};
 
// Function Call
cout<<findSum(mat)<<endl;
}
 
// This code is contributed by bgangwar59.

Java




// Java program for the above approach
import java.util.*;
 
class GFG
{
 
  // Functino to find the number after
  // processing the diagonal elements
  static int processDiagonal(ArrayList<Integer> arr)
  {
 
    // Store the required number
    int ans = 0;
 
    int getBit = 1;
 
    // Checking for each position
    for (int i = 0; i < 32; i++)
    {
 
      // Store the number of set bits
      // & non-set bits at position i
      int S = 0;
      int NS = 0;
 
      // Traverse the diagonal elements
      for(int j: arr)
      {
 
        // Update count of S if current
        // element is set at position i
        if ((getBit&j) != 0)
          S += 1;
 
        // Else update NS
        else
          NS += 1;
      }
      // If number of set bits is >
      // number of non-set bits, add
      // set bits value to the ans
      if(S > NS)
        ans += Math.pow(2,i);
      getBit <<= 1;
 
    }
 
    // Return the answer
    return ans;
  }
 
  // Function to find the sum of the
  // numbers generated after processing
  // both the diagonals of the matrix
  static int findSum(int[][] mat)
  {
 
    int i = 0;
    int j = 0;
 
    // Store the primary diagonal elements
    ArrayList<Integer> priDiag
      = new ArrayList<Integer>();
 
    while(i<mat.length){
      priDiag.add(mat[i][j]);
      i += 1;
      j += 1;
    }
 
    i = 0;
    j = mat.length - 1;
 
    // Store the secondary diagonal elements
    ArrayList<Integer> secDiag
      = new ArrayList<Integer>();
    while(i<mat.length){
      secDiag.add(mat[i][j]);
      i += 1;
      j -= 1;
    }
 
    // Function Call to get the required
    // numbers and return their sum
    return (processDiagonal(priDiag) + processDiagonal(secDiag));
 
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int[][] mat= {{1, 2, 3},{4, 5, 6},{7, 8, 9}};
 
    // Function Call
    System.out.print(findSum(mat));
  }
}
 
// This code is contributed by splevel62.

Python3




# Python program for the above approach
 
# Functino to find the number after
# processing the diagonal elements
def processDiagonal(arr):
   
  # Store the required number
  ans = 0
   
  getBit = 1
   
  # Checking for each position
  for i in range(32):
     
    # Store the number of set bits
    # & non-set bits at position i
    S = 0
    NS = 0
     
    # Traverse the diagonal elements
    for j in arr:
       
      # Update count of S if current
      # element is set at position i
      if getBit&j:
        S += 1
         
      # Else update NS
      else:
        NS += 1
     
    # If number of set bits is >
    # number of non-set bits, add
    # set bits value to the ans
    if S > NS:
      ans += 2**i
    getBit <<= 1
     
  # Return the answer
  return ans
 
# Function to find the sum of the
# numbers generated after processing
# both the diagonals of the matrix
def findSum(mat):
  i = 0
  j = 0
   
  # Store the primary diagonal elements
  priDiag = []
   
  while i<len(mat):
    priDiag.append(mat[i][j])
    i += 1
    j += 1
     
  i = 0
  j = len(mat)-1
   
  # Store the secondary diagonal elements
  secDiag = []
  while i<len(mat):
    secDiag.append(mat[i][j])
    i += 1
    j -= 1
     
  # Function Call to get the required
  # numbers and return their sum
  return processDiagonal(priDiag) + processDiagonal(secDiag)
 
# Driver Code
mat = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
 
# Function Call
print(findSum(mat))

C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG {
 
  // Functino to find the number after
  // processing the diagonal elements
  static int processDiagonal(List<int> arr)
  {
 
    // Store the required number
    int ans = 0;
 
    int getBit = 1;
 
    // Checking for each position
    for (int i = 0; i < 32; i++) {
 
      // Store the number of set bits
      // & non-set bits at position i
      int S = 0;
      int NS = 0;
 
      // Traverse the diagonal elements
      foreach(int j in arr)
      {
 
        // Update count of S if current
        // element is set at position i
        if ((getBit & j) != 0)
          S += 1;
 
        // Else update NS
        else
          NS += 1;
      }
      // If number of set bits is >
      // number of non-set bits, add
      // set bits value to the ans
      if (S > NS)
        ans += (int)Math.Pow(2, i);
      getBit <<= 1;
    }
 
    // Return the answer
    return ans;
  }
 
  // Function to find the sum of the
  // numbers generated after processing
  // both the diagonals of the matrix
  static int findSum(int[, ] mat)
  {
 
    int i = 0;
    int j = 0;
 
    // Store the primary diagonal elements
    List<int> priDiag = new List<int>();
 
    while (i < mat.GetLength(0)) {
      priDiag.Add(mat[i, j]);
      i += 1;
      j += 1;
    }
 
    i = 0;
    j = mat.GetLength(0) - 1;
 
    // Store the secondary diagonal elements
    List<int> secDiag = new List<int>();
    while (i < mat.GetLength(0)) {
      secDiag.Add(mat[i, j]);
      i += 1;
      j -= 1;
    }
 
    // Function Call to get the required
    // numbers and return their sum
    return (processDiagonal(priDiag)
            + processDiagonal(secDiag));
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    int[, ] mat
      = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
 
    // Function Call
    Console.Write(findSum(mat));
  }
}
 
// This code is contributed by ukasp.
Output: 
8

 

Time Complexity: O(N)
Auxiliary Space: O(1)

Attention reader! Don’t stop learning now. Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up
Recommended Articles
Page :