Number of cells a queen can move with obstacles on the chessborad

2.5

Consider a N X N chessboard with a Queen and K obstacles. The Queen cannot pass through obstacles. Given the position (x, y) of Queen, the task is to find the number of cells the queen can move.

Examples:

Input : N = 8, x = 4, y = 4, 
        K = 0
Output : 27


Input : N = 8, x = 4, y = 4, 
        K = 1, kx1 = 3, ky1 = 5
Output : 24

Method 1:
The idea is to iterate over the cells the queen can attack and stop until there is an obstacle or end of the board. To do that, we need to iterate horizontally, vertically and diagonally. The moves from position (x, y) can be:
(x+1, y): one step horizontal move to the right.
(x-1, y): one step horizontal move to the left.
(x+1, y+1): one step diagonal move up-right.
(x-1, y-1): one step diagonal move down-left.
(x-1, y+1): one step diagonal move left-up.
(x+1, y-1): one step diagonal move right-down.
(x, y+1): one step downward.
(x, y-1): one step upward.

Below is C++ implementation of this approach:

// C++ program to find number of cells a queen can move 
// with obstacles on the chessborad
#include<bits/stdc++.h>
using namespace std;

// Return if position is valid on chessboard
int range(int n, int x, int y)
{
  return (x <= n && x > 0 && y <= n && y > 0);
}

// Return the number of moves with a given direction
int check(int n, int x, int y, int xx, int yy, 
                  map <pair<int, int>, int> mp)
{
  int ans = 0;
  
  // Checking valid move of Queen in a direction.
  while (range(n, x, y) && ! mp[{x, y}])
  {
    x += xx;
    y += yy;
    ans++;
  }
  
  return ans;
}

// Return the number of position a Queen can move.
int numberofPosition(int n, int k, int x, int y, 
                  int obstPosx[], int obstPosy[])
{
  int x1, y1, ans = 0;
  map <pair<int, int>, int> mp;
  
  // Mapping each obstacle's position
  while(k--)
  {
    x1 = obstPosx[k];
    y1 = obstPosy[k];
    
    mp[{x1, y1}] = 1;
  }
  
  // Fetching number of position a queen can
  // move in each direction.
  ans += check(n, x + 1, y, 1, 0, mp);
  ans += check(n, x-1, y, -1, 0, mp);
  ans += check(n, x, y + 1, 0, 1, mp);
  ans += check(n, x, y-1, 0, -1, mp);
  ans += check(n, x + 1, y + 1, 1, 1, mp);
  ans += check(n, x + 1, y-1, 1, -1, mp);
  ans += check(n, x-1, y + 1, -1, 1, mp);
  ans += check(n, x-1, y-1, -1, -1, mp);
  
  return ans;
}

// Driven Program
int main()
{
  int n = 8;  // Chessboard size
  int k = 1;  // Number of obstacles
  int Qposx = 4; // Queen x position
  int Qposy = 4; // Queen y position
  int obstPosx[] = { 3 };  // x position of obstacles
  int obstPosy[] = { 5 };  // y position of obstacles
  
  cout << numberofPosition(n, k, Qposx, Qposy, 
                   obstPosx, obstPosy) << endl;
  return 0;
}

Output:

24

 

Method 2:
The idea is to iterate over the obstacles and for those who are in the queen’s path, we calculate the free cells upto that obstacle. If there is no obstacle in the path we have to calculate the number of free cells upto end of board in that direction.
For any (x1, y1) and (x2, y2):

  • If they are horizontally at same level: abs(x1 – x2 – 1)
  • If they are vertically at same level: abs(y1 – y2 – 1) is the number of free cells between.
  • If they are diagonal: both abs(x1 – x2 – 1) or abs(y1 – y2 – 1) is the number of free cells between.

Below is C++ implementation of this approach:

// C++ program to find number of cells a queen can move
// with obstacles on the chessborad
#include <bits/stdc++.h>
using namespace std;

// Return the number of position a Queen can move.
int numberofPosition(int n, int k, int x, int y,
                    int obstPosx[], int obstPosy[])
{
    // d11, d12, d21, d22 are for diagnoal distances.
    // r1, r2 are for vertical distance.
    // c1, c2 are for horizontal distance.
    int d11, d12, d21, d22, r1, r2, c1, c2;

    // Initialise the distance to end of the board.
    d11 = min( x-1, y-1 );
    d12 = min( n-x, n-y );
    d21 = min( n-x, y-1 );
    d22 = min( x-1, n-y );

    r1 = y-1;
    r2 = n-y;
    c1 = x-1;
    c2 = n-x;

    // For each obstacle find the minimum distance.
    // If obstacle is present in any direction,
    // distance will be updated.
    for (int i = 0; i < k; i++)
    {
        if ( x > obstPosx[i] && y > obstPosy[i] &&
                 x-obstPosx[i] == y-obstPosy[i] )
            d11 = min(d11, x-obstPosx[i]-1);

        if ( obstPosx[i] > x && obstPosy[i] > y &&
                  obstPosx[i]-x == obstPosy[i]-y )
            d12 = min( d12, obstPosx[i]-x-1);

        if ( obstPosx[i] > x && y > obstPosy[i] &&
                   obstPosx[i]-x == y-obstPosy[i] )
            d21 = min(d21, obstPosx[i]-x-1);

        if ( x > obstPosx[i] && obstPosy[i] > y &&
                    x-obstPosx[i] == obstPosy[i]-y )
            d22 = min(d22, x-obstPosx[i]-1);

        if ( x == obstPosx[i] && obstPosy[i] < y )
            r1 = min(r1, y-obstPosy[i]-1);

        if ( x == obstPosx[i] && obstPosy[i] > y )
            r2 = min(r2, obstPosy[i]-y-1);

        if ( y == obstPosy[i] && obstPosx[i] < x )
            c1 = min(c1, x-obstPosx[i]-1);

        if ( y == obstPosy[i] && obstPosx[i] > x )
            c2 = min(c2, obstPosx[i]-x-1);
    }

    return d11 + d12 + d21 + d22 + r1 + r2 + c1 + c2;
}

// Driver code
int main(void)
{
    int n = 8;  // Chessboard size
    int k = 1;  // number of obstacles
    int Qposx = 4; // Queen x position
    int Qposy = 4; // Queen y position
    int obstPosx[] = { 3 };  // x position of obstacles
    int obstPosy[] = { 5 };  // y position of obstacles

    cout << numberofPosition(n, k, Qposx, Qposy,
                             obstPosx, obstPosy);
    return 0;
}

This article is contributed by Anuj Chauhan. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

GATE CS Corner    Company Wise Coding Practice

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.

Recommended Posts:



2.5 Average Difficulty : 2.5/5.0
Based on 6 vote(s)










Writing code in comment? Please use ide.geeksforgeeks.org, generate link and share the link here.