Given two integers, N and M, denoting dimensions of a chessboard. The task is to count ways to place a black and a white knight on an N * M chessboard such that they do not attack each other? The knights have to be placed on different squares. A knight can move two squares horizontally and one square vertically (L shaped), or two squares vertically and one square horizontally (L shaped). The knights attack each other if one can reach the other in one move.
Examples:
Input: N=2, M=2 Output: 12 Explanation: We can place a black and a white knight in 12 possible ways such that none of them attracts each other. Input: N=2, M=3 Output: 26
Naive Approach:
- Naive approach is to for each cell count number of ways knight can be placed so that both can attack each other and then subtract count from total arrangements.
- Total arrangements can be calculated as:
Total arrangements = M * N * (M * N - 1)
Because for each cell we can place other knight at (M * N – 1) cells and total M * N cell will be there.
C++
// C++ program to count arrangements // of two knight so that they do not // attack each other. #include <iostream> using namespace std; // Function returns the count // of arrangments long long Solve( int n, int m) { int X_axis[]{ -2, -1, 1, 2}; int Y_axis[]{ 1, 2, 2, 1 }; long long ret = 0; for ( int i = 0; i < m; ++i) { for ( int j = 0; j < n; ++j) { for ( int k = 0; k < 4; ++k) { int x = i + X_axis[k], y = j + Y_axis[k]; if (x >= 0 && x < m && y >= 0 && y < n) ++ret; } } } long long Total = m * n; Total = Total * (Total - 1) / 2; return 2 * (Total - ret); } // Driver code int main() { int N = 2, M = 3; cout << Solve(N, M) << endl; return 0; } |
Java
// Java program to count arrangements // of two knight so that they do not // attack each other. import java.io.*; import java.util.*; class GFG { // Function returns the count // of arrangments static long Solve( int n, int m) { int X_axis[] = { - 2 , - 1 , 1 , 2 }; int Y_axis[] = { 1 , 2 , 2 , 1 }; long ret = 0 ; for ( int i = 0 ; i < m; ++i) { for ( int j = 0 ; j < n; ++j) { for ( int k = 0 ; k < 4 ; ++k) { int x = i + X_axis[k]; int y = j + Y_axis[k]; if (x >= 0 && x < m && y >= 0 && y < n) ++ret; } } } long Total = m * n; Total = Total * (Total - 1 ) / 2 ; return 2 * (Total - ret); } // Driver code public static void main(String[] args) { int N = 2 , M = 3 ; System.out.println(Solve(N, M)); } } // This code is contributed by coder001 |
Python3
# Python3 program to count arrangements # of two knight so that they do not # attack each other # Function returns the count # of arrangments def Solve(n, m): X_axis = [] X_axis = [ - 2 , - 1 , 1 , 2 ] Y_axis = [] Y_axis = [ 1 , 2 , 2 , 1 ] ret = 0 for i in range (m): for j in range (n): for k in range ( 4 ): x = i + X_axis[k] y = j + Y_axis[k] if (x > = 0 and x < m and y > = 0 and y < n): ret + = 1 Total = m * n Total = Total * (Total - 1 ) / / 2 return 2 * (Total - ret) # Driver code N = 2 M = 3 print (Solve(N, M)) # This code is contributed by sanjoy_62 |
C#
// C# program to count arrangements // of two knight so that they do not // attack each other. using System; class GFG{ // Function returns the count // of arrangments static long Solve( int n, int m) { int []X_axis = { -2, -1, 1, 2}; int []Y_axis = { 1, 2, 2, 1 }; long ret = 0; for ( int i = 0; i < m; ++i) { for ( int j = 0; j < n; ++j) { for ( int k = 0; k < 4; ++k) { int x = i + X_axis[k]; int y = j + Y_axis[k]; if (x >= 0 && x < m && y >= 0 && y < n) ++ret; } } } long Total = m * n; Total = Total * (Total - 1) / 2; return 2 * (Total - ret); } // Driver code public static void Main(String[] args) { int N = 2, M = 3; Console.Write(Solve(N, M)); } } // This code is contributed by shivanisinghss2110 |
26
Time complexity: O(N * M)
Space complexity: O(1).
Efficient Approach:
- Suppose board has N rows and M columns.Now first consider knight to move 2 steps in horizontal direction and 1 step in vertical.So if we are at (i, j) after such moves we can reach at (i+2, j+1), (i+2, j-1), (i-2, j+1), (i-2, j-1).To have (i+2) inside board we can have our positions 0 to N-3 i.e we have to leave last two rows otherwise (i+2) will be out of board.similarly for (i-2) range possible if 2 to N.
- Similarly for (j+1) range will be 0 to N-2, and for (j+1) range will be 1 to M-1 i.e one column less in each case.
- So, arrangements in this case where attack possible equal to 4 * (N – 2) * (M – 1)
- Similarly if we consider two steps in vertical and one step in horizontal we will have one less row and two less col so that two knight can attack each other.
- We will subtract this arrangements from total arrangements which is M * N * (M * N – 1).
C++
// C++ program to count arrangements // of two knight so that they do not // attack each other. #include <iostream> using namespace std; // Function returns the count // of arrangments long long Solve( int N, int M) { // Total arrangements int ans = (N * M - 1) * N * M; if (N >= 1 && M >= 2) { // Attacks possible in one horizontal // and two vertical steps ans -= (4 * (N - 1) * (M - 2)); } if (N >= 2 && M >= 1) { // Attacks possible in Two horizontal // and one vertical steps ans -= (4 * (N - 2) * (M - 1)); } return ans; } // Driver code int main() { int N = 2, M = 3; cout << Solve(N, M) << endl; return 0; } |
Java
// Java program to count arrangements // of two knight so that they do not // attack each other. import java.io.*; import java.util.*; class GFG { // Function returns the count // of arrangments static long Solve( int N, int M) { // Total arrangements int ans = (N * M - 1 ) * N * M; if (N >= 1 && M >= 2 ) { // Attacks possible in one horizontal // and two vertical steps ans -= ( 4 * (N - 1 ) * (M - 2 )); } if (N >= 2 && M >= 1 ) { // Attacks possible in Two horizontal // and one vertical steps ans -= ( 4 * (N - 2 ) * (M - 1 )); } return ans; } // Driver code public static void main(String[] args) { int N = 2 , M = 3 ; System.out.println(Solve(N, M)); } } // This code is contributed by coder001 |
Python3
# Python3 program to count arrangements # of two knight so that they do not # attack each other. # Function returns the count # of arrangments def Solve(N, M): # Total arrangements ans = (N * M - 1 ) * N * M if (N > = 1 and M > = 2 ): # Attacks possible in one horizontal # and two vertical steps ans - = ( 4 * (N - 1 ) * (M - 2 )) if (N > = 2 and M > = 1 ): # Attacks possible in Two horizontal # and one vertical steps ans - = ( 4 * (N - 2 ) * (M - 1 )) return ans # Driver code N = 2 M = 3 print (Solve(N, M)) # This code is contributed by sanjoy_62 |
C#
// C# program to count arrangements // of two knight so that they do not // attack each other. using System; class GFG{ // Function returns the count // of arrangments static long Solve( int N, int M) { // Total arrangements int ans = (N * M - 1) * N * M; if (N >= 1 && M >= 2) { // Attacks possible in one horizontal // and two vertical steps ans -= (4 * (N - 1) * (M - 2)); } if (N >= 2 && M >= 1) { // Attacks possible in Two horizontal // and one vertical steps ans -= (4 * (N - 2) * (M - 1)); } return ans; } // Driver code static public void Main () { int N = 2, M = 3; Console.Write(Solve(N, M)); } } // This code is contributed by ShubhamCoder |
26
Time Complexity: O(1).
Space Complexity: O(1).
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.