Fairy Chess


Problem Statement :


Let's play Fairy Chess!

You have an n*n chessboard. An s-leaper is a chess piece which can move from some square (x0,y0) to some square (x1,y1) if abs(x0-x1) + abs(y0-y1) <= s; however, its movements are restricted to up, down, left, and right within the confines of the chessboard, meaning that diagonal moves are not allowed. In addition, the leaper cannot leap to any square that is occupied by a pawn.

Given the layout of the chessboard, can you determine the number of ways a leaper can move m times within the chessboard?

Note: abs(x) refers to the absolute value of some integer, x.

Input Format

The first line contains an integer, q, denoting the number of queries. Each query is described as follows:

1.The first line contains three space-separated integers denoting n, m, and s, respectively.
2.Each line i of the n subsequent lines contains n characters. The jth character in the ith line describes the contents of square (i,j) according to the following key:
. indicates the location is empty.
P indicates the location is occupied by a pawn.
L indicates the location of the leaper.
Constraints

1 <= q <= 10
1 <= m <= 200
There will be exactly one L character on the chessboard.
The s-leaper can move up (), down (), left (), and right () within the confines of the chessboard. It cannot move diagonally.



Solution :



title-img


                            Solution in C :

In C++ :






#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
using namespace std;

const int P = 1000000007;
const int maxN = 200;
const int maxS = 200;

int TN, TC;

int N, M, S, K;

char tmp[maxN + 1];
char board[maxN][maxN];

int sx, sy;

int num[maxN][maxN];
int sum[2][maxN][maxN];

#define PLUS(x, v) \
{ \
  x += v; \
  if (x >= P) \
    x -= P; \
}

#define MINUS(x, v) \
{ \
  x -= v; \
  if (x < 0) \
    x += P; \
}

void find_leaper (int &px, int &py)
{
  for (int x = 0; x < N; ++x)
    for (int y = 0; y < N; ++y)
      if (board[x][y] == 'L')
      {
        px = x;
        py = y;
        return;
      }
}

void coor_trans (int x, int y, int &tx, int &ty, int &s)
{
  if (!((x + y) & 1))
  {
    s = 0;
    tx = (x + y) >> 1;
    ty = ((y - x) >> 1) + ((N - 1) >> 1);
  }
  else
  {
    s = 1;
    tx = (x + y) >> 1;
    ty = ((y - x + 1) >> 1) + ((N - 2) >> 1);
  }
}

int square_sum (int x, int y, int h)
{
  int tx, ty, s;
  coor_trans(x, y, tx, ty, s);
  int tx2 = tx - h, ty2 = ty - h;
  if (tx >= N)
    tx = N - 1;
  if (ty >= N)
    ty = N - 1;
  if (tx2 >= N)
    tx2 = N - 1;
  if (ty2 >= N)
    ty2 = N - 1;
  int r = sum[s][tx][ty];
  if (tx2 >= 0)
    MINUS(r, sum[s][tx2][ty]);
  if (ty2 >= 0)
    MINUS(r, sum[s][tx][ty2]);
  if (tx2 >= 0 && ty2 >= 0)
    PLUS(r, sum[s][tx2][ty2]);
  return r;
}

int solve ()
{
  for (int x = 0; x < N; ++x)
    for (int y = 0; y < N; ++y)
      if (board[x][y] != 'P')
        num[x][y] = 1;
      else
        num[x][y] = 0;

  for (int u = 0; u < M; ++u)
  {
    memset(sum, 0, sizeof(sum));
    for (int x = 0; x < N; ++x)
      for (int y = 0; y < N; ++y)
        if (board[x][y] != 'P')
        {
          int tx, ty, s;
          coor_trans(x, y, tx, ty, s);
          sum[s][tx][ty] = num[x][y];
        }

    for (int s = 0; s < 2; ++s)
    {
      for (int y = 1; y < N; ++y)
        PLUS(sum[s][0][y], sum[s][0][y - 1]);
      for (int x = 1; x < N; ++x)
      {
        PLUS(sum[s][x][0], sum[s][x - 1][0]);
        for (int y = 1; y < N; ++y)
        {
          int &r = sum[s][x][y];
          PLUS(r, sum[s][x - 1][y]);
          PLUS(r, sum[s][x][y - 1]);
          MINUS(r, sum[s][x - 1][y - 1]);
        }
      }
    }

    for (int x = 0; x < N; ++x)
      for (int y = 0; y < N; ++y)
        if (board[x][y] != 'P')
        {
          num[x][y] = square_sum(x, y + S, S + 1) + square_sum(x, y + S - 1, S);
          if (num[x][y] >= P)
            num[x][y] -= P;
        }
  }

  return num[sx][sy];
}

int main ()
{
  scanf("%d", &TN);
  for (TC = 1; TC <= TN; ++TC)
  {
    scanf("%d%d%d ", &N, &M, &S);
    K = N + (S + 1) / 2;
    for (int x = 0; x < N; ++x)
    {
      gets(tmp);
      memcpy(board[x], tmp, N);
    }
    find_leaper(sx, sy);
    int ans = solve();
    printf("%d\n", ans);
  }
}








In Java :





import java.util.Scanner;

public class Solution {

	private static final int MOD_PRIME = 1000000007;

	public static int addModulo(int x, int y) {
		int s = x + y;
		if (s >= MOD_PRIME)
			s -= MOD_PRIME;
		return s;
	}

	public static int subtractModulo(int x, int y) {
		int d = x - y;
		if (d < 0)
			d += MOD_PRIME;
		return d;
	}

	public static int query(int[][] sum, int x, int y, int s) {
		int n = sum.length;
		int rx = n / 2 + x - y;
		int ry = x + y + 1;
		int high_x = Math.min(rx + s, n - 1);
		int low_x = Math.max(rx - s, 1);
		int high_y = Math.min(ry + s, n - 1);
		int low_y = Math.max(ry - s, 1);
		int pos = addModulo(sum[high_x][high_y], sum[low_x - 1][low_y - 1]);
		int neg = addModulo(sum[high_x][low_y - 1], sum[low_x - 1][high_y]);
		return subtractModulo(pos, neg);
	}

	public static void createSumTable(int[][] sum, int[][] matrix) {
		for (int i = 0; i < matrix.length; i++) {
			int partialSum = 0;
			for (int j = 0; j < matrix[i].length; j++) {
				partialSum = addModulo(partialSum, matrix[i][j]);
				sum[i][j] = partialSum;
				if (i > 0)
					sum[i][j] = addModulo(sum[i][j], sum[i - 1][j]);
			}
		}
	}

	public static final void solveProblem(Scanner in) {
		String line = in.nextLine();
		String tokens[] = line.split(" ");
		int n = Integer.parseInt(tokens[0]);
		int m = Integer.parseInt(tokens[1]);
		int s = Integer.parseInt(tokens[2]);

		int[][] rotated = new int[2 * n][2 * n];
		int[][] sum = new int[2 * n][2 * n];
		int[][] next = new int[2 * n][2 * n];

		int lx = -1, ly = -1;
		for (int i = 0; i < n; i++) {
			line = in.nextLine();
			for (int j = 0; j < line.length(); j++) {
				char ch = line.charAt(j);
				if (ch != 'P') {
					rotated[n + i - j][i + j + 1] = 1;
					if (ch == 'L') {
						lx = i;
						ly = j;
					}
				}
			}
		}
		createSumTable(sum, rotated);

		for (int k = 2; k <= m; k++) {
			for (int i = 0; i < n; i++)
				for (int j = 0; j < n; j++) {
					int x = n + i - j;
					int y = i + j + 1;
					if (rotated[x][y] != 0)
						next[x][y] = query(sum, i, j, s);
				}
			int[][] tmp = next;
			next = rotated;
			rotated = tmp;
			createSumTable(sum, rotated);
		}

		System.out.println(query(sum, lx, ly, s));
	}

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);

		int numTests = Integer.parseInt(in.nextLine());
		for (int i = 0; i < numTests; i++)
			solveProblem(in);

		in.close();
	}

}








In C :






#include <stdio.h>

#define P 1000000007

long long ll,t,a[2][1000][1000],mm,mmm,p[1010][1010];
long long r[1010][1010],i,j,k,l,m,n;
char s[210][210];

/*
long long bb(long long ll, long long ii, long long jj)
{

if(ii<0 || ii>=n || jj<0 || jj>=n) return 0;

return a[ll][ii][jj];
}
*/

int main()
{

scanf("%lld",&t);
while(t--)
{
scanf("%lld %lld %lld\n",&n,&m,&k);
for(i=0;i<n;i++) scanf("%s\n",s[i]);

/*
for(i=0;i<n;i++)
 for(j=0;j<n;j++)
  for(l=0;l<0;l++) a[l][i][j]=0;
*/

for(i=0;i<1000;i++) 
 for(j=0;j<1000;j++) 
  a[0][i][j] = a[1][i][j] = 0;

for(i=0;i<n;i++) 
 for(j=0;j<n;j++)    
    if(s[i][j]=='L') a[0][i+500][j+500] = 1;
 
 for(i=0;i<1000;i++) 
  for(j=0;j<1000;j++) p[i][j]= r[i][j] =0;
 
 //for(l=0;l<m;l++)
l=0;
ll=1;
 
 while(m--)
   {
      
    for(i=500;i<n+500;i++)
    {
     for(j=-k+500;j<n+500;j++) 
       { 
         p[i][j] = (p[i-1][j+1] + a[l][i][j] - a[l][i-1-k][j+1+k])%P;
        }
    }

    for(i=n+500;i<n+k+500;i++)
    {
     for(j=500;j<n+500;j++) 
       { 
         p[i][j] = (p[i-1][j+1] + a[l][i][j] - a[l][i-1-k][j+1+k])%P;
        }
    }
    
    
   for(i=n-1+500;i>=500-1;i--)
   {
    for(j=-k+500;j<=n+500;j++)
        {
         r[i][j] = (r[i+1][j+1] + a[l][i][j] - a[l][i+1+k][j+1+k])%P;
          }
   }
   
   for(i=-2+500;i>=-k+500;i--)
   {
    for(j=500;j<=n+500;j++)
        {
         r[i][j] = (r[i+1][j+1] + a[l][i][j] - a[l][i+1+k][j+1+k])%P;
          }
   }


j = 500-1;
//jj = 500+j;
 mmm=0;
 for(i=-k+500;i<500;i++)
   {
//   ii = i+500;
       mmm = (mmm + p[i+k][j])%P;
              //+ r[i][j-k] 
              //- a[l][i+k][j]
              //- p[i-1][j-k] - r[i-1-k][j] 
              //+ a[l][i-1-k][j])%P;
   
   }

 for(j=500;j<n+500;j++)
 {   
//     jj = j+500;
     i = 500-1;
//     ii= 500+i;
     
       mmm = (mmm + p[i+k][j] + r[i-k][j] - a[l][i][j+k]
              - p[i][j-1-k] - r[i][j-1-k] + a[l][i][j-k-1])%P; 
     
      mm = mmm;
     
     for(i=500;i<n+500;i++) 
      {
//       ii = i+500;
       mm = (mm + p[i+k][j] + r[i][j-k] - a[l][i+k][j]
              - p[i-1][j-k] - r[i-1-k][j] + a[l][i-1-k][j])%P;
   
   
 //  printf("mm %lld %lld %lld\n",i,j,mm);
       
       
          if(s[i-500][j-500]!='P') a[ll][i][j] = mm;
                      else a[ll][i][j] = 0;
      
      } 
  } 

l = (l+1)%2;
ll = (ll+1)%2;

/*
for(i=500;i<n+500;i++)
 {
 for(j=500;j<n+500;j++) printf("%lld ",a[l][i][j]);
 printf("\n");
 }

printf("--------------\n");
*/
}


mm = 0;
for(i=500;i<n+500;i++)
 for(j=500;j<n+500;j++) mm = (mm + a[l][i][j])%P;
 
 printf("%lld\n",(mm+P)%P);

//return 0;

}


return 0;
}
                        








View More Similar Problems

Subsequence Weighting

A subsequence of a sequence is a sequence which is obtained by deleting zero or more elements from the sequence. You are given a sequence A in which every element is a pair of integers i.e A = [(a1, w1), (a2, w2),..., (aN, wN)]. For a subseqence B = [(b1, v1), (b2, v2), ...., (bM, vM)] of the given sequence : We call it increasing if for every i (1 <= i < M ) , bi < bi+1. Weight(B) =

View Solution →

Kindergarten Adventures

Meera teaches a class of n students, and every day in her classroom is an adventure. Today is drawing day! The students are sitting around a round table, and they are numbered from 1 to n in the clockwise direction. This means that the students are numbered 1, 2, 3, . . . , n-1, n, and students 1 and n are sitting next to each other. After letting the students draw for a certain period of ti

View Solution →

Mr. X and His Shots

A cricket match is going to be held. The field is represented by a 1D plane. A cricketer, Mr. X has N favorite shots. Each shot has a particular range. The range of the ith shot is from Ai to Bi. That means his favorite shot can be anywhere in this range. Each player on the opposite team can field only in a particular range. Player i can field from Ci to Di. You are given the N favorite shots of M

View Solution →

Jim and the Skyscrapers

Jim has invented a new flying object called HZ42. HZ42 is like a broom and can only fly horizontally, independent of the environment. One day, Jim started his flight from Dubai's highest skyscraper, traveled some distance and landed on another skyscraper of same height! So much fun! But unfortunately, new skyscrapers have been built recently. Let us describe the problem in one dimensional space

View Solution →

Palindromic Subsets

Consider a lowercase English alphabetic letter character denoted by c. A shift operation on some c turns it into the next letter in the alphabet. For example, and ,shift(a) = b , shift(e) = f, shift(z) = a . Given a zero-indexed string, s, of n lowercase letters, perform q queries on s where each query takes one of the following two forms: 1 i j t: All letters in the inclusive range from i t

View Solution →

Counting On a Tree

Taylor loves trees, and this new challenge has him stumped! Consider a tree, t, consisting of n nodes. Each node is numbered from 1 to n, and each node i has an integer, ci, attached to it. A query on tree t takes the form w x y z. To process a query, you must print the count of ordered pairs of integers ( i , j ) such that the following four conditions are all satisfied: the path from n

View Solution →