Count pair of bishops that will attack each other on a N x N chessboard

Last Updated : 23 Jul, 2025

Given a N x N chessboard and the position of X bishops on it, the task is to calculate the count of pairs of bishops such that they attack each other. Note that while considering a pair of bishops, all the other bishops are not considered to be on the board.

Example:

Input: N = 5, bishops[][] = {{2, 1}, {3, 2}, {2, 3}}
Output: 2
Explanation: The bishops on the positions {2, 1} and {3, 2} and bishops on the positions {3, 2} and {2, 3} attack each other.

Input: N = 10, bishops[][] = {{1, 1}, {1, 5}, {3, 3}, {5, 1}, {5, 5}}
Output: 6

 

Approach: The given problem can be solved using basic combinatorics. Since all the bishops that lie on the same diagonal will attack each other, all possible pairs of bishops that are on the same diagonal that can be formed will attack each other. Therefore, traverse the matrix for all diagonals in both left and right directions and count the number of bishops on the current diagonal in a variable cnt. Now for each diagonal, the number of attacking bishops will be cntC2.

Below is the implementation of the above approach:

C++
#include <bits/stdc++.h>
using namespace std;

int board[20][20];

int countPairs(int N, vector<pair<int, int> > bishops)
{
    // Set all bits to 0
    memset(board, 0, sizeof(board));

    // Set all the bits
    // having bishop to 1
    for (int i = 0; i < bishops.size(); i++) {
        board[bishops[i].first][bishops[i].second] = 1;
    }

    // Stores the final answer
    int ans = 0;

    // Loop to traverse the matrix
    // diagonally in left direction
    for (int s = 2; s <= 2 * N; s++) {

        // Stores count of bishop
        // in the current diagonal
        int cnt = 0;

        for (int i = 1, j = s - i;
             max(i, j) <= min(N, s - 1); i++, j--) {
            if (board[j][i - j] == 1)

                // Update cnt
                cnt++;
        }

        // Update the answer
        if (cnt > 1)
            ans += ((cnt + 1) * cnt) / 2;
    }

    // Loop to traverse the matrix
    // diagonally in right direction
    for (int s = 2; s <= 2 * N; s++) {

        // Stores count of bishop
        // in the current diagonal
        int cnt = 0;

        for (int i = 1, j = s - i;
             max(i, j) <= min(N, s - 1); i++, j--) {
            if (board[i][N - j + 1] == 1)

                // Update cnt
                cnt++;
        }

        // Update the answer
        if (cnt > 1)
            ans += ((cnt + 1) * cnt) / 2;
    }

    // Return answer
    return ans;
}

// Driver code
int main()
{
    int N = 10;
    vector<pair<int, int> > bishops = {
        { 1, 1 }, { 1, 5 }, { 3, 3 }, { 5, 1 }, { 5, 5 }
    };

    cout << countPairs(N, bishops);

    return 0;
}
Java
import java.util.*;
class GFG
{
  static int [][]board = new int[20][20];

  static int countPairs(int N, int[][] bishops)
  {

    // Set all the bits
    // having bishop to 1
    for (int i = 0; i < bishops.length; i++) {
      board[bishops[i][0]][bishops[i][1]] = 1;
    }

    // Stores the final answer
    int ans = 0;

    // Loop to traverse the matrix
    // diagonally in left direction
    for (int s = 2; s <= 2 * N; s++) {

      // Stores count of bishop
      // in the current diagonal
      int cnt = 0;

      for (int i = 1, j = s - i;
           Math.max(i, j) <= Math.min(N, s - 1)&&i-j>0; i++, j--) {
        if (board[j][i - j] == 1)

          // Update cnt
          cnt++;
      }

      // Update the answer
      if (cnt > 1)
        ans += ((cnt + 1) * cnt) / 2;
    }

    // Loop to traverse the matrix
    // diagonally in right direction
    for (int s = 2; s <= 2 * N; s++) {

      // Stores count of bishop
      // in the current diagonal
      int cnt = 0;

      for (int i = 1, j = s - i;
           Math.max(i, j) <= Math.min(N, s - 1); i++, j--) {
        if (board[i][N - j + 1] == 1)

          // Update cnt
          cnt++;
      }

      // Update the answer
      if (cnt > 1)
        ans += ((cnt + 1) * cnt) / 2;
    }

    // Return answer
    return ans;
  }

  // Driver code
  public static void main(String[] args)
  {
    int N = 10;
    int[][] bishops = {
      { 1, 1 }, { 1, 5 }, { 3, 3 }, { 5, 1 }, { 5, 5 }
    };

    System.out.print(countPairs(N, bishops));

  }
}

// This code is contributed by 29AjayKumar 
Python
# Python program for above approach
board = [[0 for i in range(20)] for j in range(20)]

def countPairs(N, bishops):

    # Set all the bits
    # having bishop to 1
    for i in range(len(bishops)):
        board[bishops[i][0]][bishops[i][1]] = 1

    # Stores the final answer
    ans = 0

    # Loop to traverse the matrix
    # diagonally in left direction
    for s in range(2, (2 * N) + 1):

        # Stores count of bishop
        # in the current diagonal
        cnt = 0

        i = 1
        j = s - i
        while(max(i, j) <= min(N, s - 1)):
            if (board[j][i - j] == 1):
                # Update cnt
                cnt += 1
            i += 1
            j -= 1

        # Update the answer
        if (cnt > 1):
            ans += ((cnt + 1) * cnt) // 2

    # Loop to traverse the matrix
    # diagonally in right direction
    for s in range(2, (2 * N) + 1):

        # Stores count of bishop
        # in the current diagonal
        cnt = 0

        i = 1
        j = s - i
        while(max(i, j) <= min(N, s - 1)):
           
            if (board[i][N - j + 1] == 1):
                # Update cnt
                cnt += 1
            i += 1
            j -= 1

        # Update the answer
        if (cnt > 1):
            ans += ((cnt + 1) * cnt) // 2

    # Return answer
    return ans

# Driver code
N = 10
bishops = [[1, 1], [1, 5], [3, 3], [5, 1], [5, 5]]
print(countPairs(N, bishops))

# This code is contributed by gfgking
C#
using System;
class GFG
{
    static int[,] board = new int[20,20];
    static int countPairs(int N, int[,] bishops)
    {

        // Set all the bits
        // having bishop to 1
        for (int i = 0; i < bishops.GetLength(0); i++)
        {
            board[bishops[i,0], bishops[i,1]] = 1;
        }

        // Stores the final answer
        int ans = 0;

        // Loop to traverse the matrix
        // diagonally in left direction
        for (int s = 2; s <= 2 * N; s++)
        {

            // Stores count of bishop
            // in the current diagonal
            int cnt = 0;

            for (int i = 1, j = s - i;
                 Math.Max(i, j) <= Math.Min(N, s - 1) && i - j > 0; i++, j--)
            {
                if (board[j,i - j] == 1)

                    // Update cnt
                    cnt++;
            }

            // Update the answer
            if (cnt > 1)
                ans += ((cnt + 1) * cnt) / 2;
        }

        // Loop to traverse the matrix
        // diagonally in right direction
        for (int s = 2; s <= 2 * N; s++)
        {

            // Stores count of bishop
            // in the current diagonal
            int cnt = 0;

            for (int i = 1, j = s - i;
                 Math.Max(i, j) <= Math.Min(N, s - 1); i++, j--)
            {
                if (board[i,N - j + 1] == 1)

                    // Update cnt
                    cnt++;
            }

            // Update the answer
            if (cnt > 1)
                ans += ((cnt + 1) * cnt) / 2;
        }

        // Return answer
        return ans;
    }

    // Driver code
    public static void Main()
    {
        int N = 10;
        int[,] bishops = new int[5, 2]{{ 1, 1 }, { 1, 5 }, { 3, 3 }, { 5, 1 }, { 5, 5 }};

        Console.Write(countPairs(N, bishops));

    }
}

// This code is contributed by Saurabh Jaiswal
JavaScript
<script>
        
    // JavaScript program for above approach
    let board = new Array(20).fill(0).map(() => new Array(20).fill(0));

    const countPairs = (N, bishops) => {

        // Set all the bits
        // having bishop to 1
        for (let i = 0; i < bishops.length; i++) {
            board[bishops[i][0]][bishops[i][1]] = 1;
        }

        // Stores the final answer
        let ans = 0;

        // Loop to traverse the matrix
        // diagonally in left direction
        for (let s = 2; s <= 2 * N; s++) {

            // Stores count of bishop
            // in the current diagonal
            let cnt = 0;

            for (let i = 1, j = s - i;
                Math.max(i, j) <= Math.min(N, s - 1); i++, j--) {
                if (board[j][i - j] == 1)

                    // Update cnt
                    cnt++;
            }

            // Update the answer
            if (cnt > 1)
                ans += ((cnt + 1) * cnt) / 2;
        }

        // Loop to traverse the matrix
        // diagonally in right direction
        for (let s = 2; s <= 2 * N; s++) {

            // Stores count of bishop
            // in the current diagonal
            let cnt = 0;

            for (let i = 1, j = s - i;
                Math.max(i, j) <= Math.min(N, s - 1); i++, j--) {
                if (board[i][N - j + 1] == 1)

                    // Update cnt
                    cnt++;
            }

            // Update the answer
            if (cnt > 1)
                ans += ((cnt + 1) * cnt) / 2;
        }

        // Return answer
        return ans;
    }

    // Driver code
    let N = 10;
    let bishops = [
        [1, 1], [1, 5], [3, 3], [5, 1], [5, 5]
    ];

    document.write(countPairs(N, bishops));

// This code is contributed by rakeshsahni

</script>

Output
6

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

Approach: Optimized Diagonal Counting with Dictionary

To determine the number of bishop pairs that can attack each other on a chessboard, we can optimize the count by focusing on the bishops' positions directly rather than iterating over the entire board. Since bishops attack each other if they lie on the same diagonal, we can utilize two hash maps (or dictionaries in Python) to count bishops on each diagonal efficiently.

Steps:

  • Two Diagonal Categories: Diagonals on a chessboard can be categorized into those running from the top-left to bottom-right (/ shaped) and those from the top-right to bottom-left (\ shaped).
  • Diagonal Representation:
  • For /(right diagonal) shaped diagonals, use i + j as a unique identifier for diagonals.
  • For \(left diagonal) shaped diagonals, use i - j as a unique identifier for diagonals.
  • Count Bishops per Diagonal: Use dictionaries to keep track of how many bishops are on each unique diagonal.
  • Calculate Pairs Using Combinatorics: If k bishops are on the same diagonal, the number of ways to choose two bishops (pairs) from them is given by the combination formula C(k, 2) = k * (k - 1) / 2.
C++
#include <iostream>
#include <unordered_map>
#include <vector>

// Function to calculate pairs from n items
int countPairs(int n)
{
    if (n < 2)
        return 0;
    return (n * (n - 1)) / 2;
}

// Function to count the number of pairs of bishops that can
// attack each other
int countAttackingBishopPairs(
    int N, const std::vector<std::pair<int, int> >& bishops)
{
    std::unordered_map<int, int>
        diag1; // Hash map to count bishops on (i + j)
               // diagonals
    std::unordered_map<int, int>
        diag2; // Hash map to count bishops on (i - j)
               // diagonals

    // Populate the hash maps with bishop counts on each
    // diagonal
    for (const auto& bishop : bishops) {
        int x = bishop.first;
        int y = bishop.second;
        diag1[x + y]++;
        diag2[x - y]++;
    }

    int ans = 0;

    // Sum the number of attacking pairs on each (i + j)
    // diagonal
    for (const auto& p : diag1) {
        ans += countPairs(p.second);
    }

    // Sum the number of attacking pairs on each (i - j)
    // diagonal
    for (const auto& p : diag2) {
        ans += countPairs(p.second);
    }

    return ans;
}

// Example usage
int main()
{
    std::vector<std::pair<int, int> > bishops = {
        { 1, 1 }, { 1, 5 }, { 3, 3 }, { 5, 1 }, { 5, 5 }
    };
    int N = 10;
    std::cout << countAttackingBishopPairs(N, bishops)
              << std::endl; // Output: 6
    return 0;
}
Java
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {
    // Function to calculate pairs from n items
    static int countPairs(int n)
    {
        if (n < 2)
            return 0;
        return (n * (n - 1)) / 2;
    }

    // Function to count the number of pairs of bishops that
    // can attack each other
    static int countAttackingBishopPairs(
        int N, List<Map.Entry<Integer, Integer> > bishops)
    {
        Map<Integer, Integer> diag1
            = new HashMap<>(); // Hash map to count bishops
                               // on (i + j) diagonals
        Map<Integer, Integer> diag2
            = new HashMap<>(); // Hash map to count bishops
                               // on (i - j) diagonals

        // Populate the hash maps with bishop counts on each
        // diagonal
        for (Map.Entry<Integer, Integer> bishop : bishops) {
            int x = bishop.getKey();
            int y = bishop.getValue();
            diag1.put(x + y,
                      diag1.getOrDefault(x + y, 0) + 1);
            diag2.put(x - y,
                      diag2.getOrDefault(x - y, 0) + 1);
        }

        int ans = 0;

        // Sum the number of attacking pairs on each (i + j)
        // diagonal
        for (int count : diag1.values()) {
            ans += countPairs(count);
        }

        // Sum the number of attacking pairs on each (i - j)
        // diagonal
        for (int count : diag2.values()) {
            ans += countPairs(count);
        }

        return ans;
    }

    // Example usage
    public static void main(String[] args)
    {
        List<Map.Entry<Integer, Integer> > bishops
            = List.of(Map.entry(1, 1), Map.entry(1, 5),
                      Map.entry(3, 3), Map.entry(5, 1),
                      Map.entry(5, 5));
        int N = 10;
        System.out.println(countAttackingBishopPairs(
            N, bishops)); // Output: 6
    }
}
Python
def countPairs(N, bishops):
    # Dictionaries for diagonals
    diag1 = {}  # i + j
    diag2 = {}  # i - j

    # Count bishops on each diagonal
    for x, y in bishops:
        if (x + y) not in diag1:
            diag1[x + y] = 0
        if (x - y) not in diag2:
            diag2[x - y] = 0
        diag1[x + y] += 1
        diag2[x - y] += 1

    # Function to calculate pairs in n items
    def count_pairs(n):
        if n < 2:
            return 0
        return (n * (n - 1)) // 2

    # Calculate pairs of bishops that can attack each other
    ans = sum(count_pairs(count) for count in diag1.values()) + \
        sum(count_pairs(count) for count in diag2.values())

    return ans


# Example usage
N = 10
bishops = [[1, 1], [1, 5], [3, 3], [5, 1], [5, 5]]
print(countPairs(N, bishops))  # Output: 6
JavaScript
// Function to calculate pairs from n items
function countPairs(n) {
    if (n < 2)
        return 0;
    return (n * (n - 1)) / 2;
}

// Function to count the number of pairs of bishops that
// can attack each other
function countAttackingBishopPairs(N, bishops) {
    const diag1 = new Map(); // Map to count bishops on (i + j) diagonals
    const diag2 = new Map(); // Map to count bishops on (i - j) diagonals

    // Populate the maps with bishop counts on each diagonal
    for (const [x, y] of bishops) {
        diag1.set(x + y, (diag1.get(x + y) || 0) + 1);
        diag2.set(x - y, (diag2.get(x - y) || 0) + 1);
    }

    let ans = 0;

    // Sum the number of attacking pairs on each (i + j) diagonal
    for (const count of diag1.values()) {
        ans += countPairs(count);
    }

    // Sum the number of attacking pairs on each (i - j) diagonal
    for (const count of diag2.values()) {
        ans += countPairs(count);
    }

    return ans;
}

// Example usage
const bishops = [
    [1, 1],
    [1, 5],
    [3, 3],
    [5, 1],
    [5, 5]
];
const N = 10;
console.log(countAttackingBishopPairs(N, bishops)); // Output: 6

Output
6

Time Complexity: O(X), where X is the number of bishops. The computation directly depends on the number of bishops and not on the size of the board N.

Auxilary Space: O(X), where X is the number of bishops. This accounts for the space used by the dictionaries to track bishops on each diagonal.

Comment