计蒜客 马踏过河卒

AA 点有一个过河卒,需要走到目标 BB 点。卒行走规则:可以向下、或者向右。同时在棋盘上的任一点有一个对方的马(如上图的 CC 点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。例如上图 CC 点上的马可以控制 99 个点(图中的 P1,P2 \cdots P8P1,P2P8 和 CC)。卒不能通过对方马的控制点。

棋盘用坐标表示,AA 点(0000)、BB 点(nnmm)、CC 点(c_xcxc_ycy)(0 < c_x < n \leq 200<cx<n200 < c_y < m \leq 200<cy<m20)。现在要求你计算出过河卒从 AA 点能够到达 BB 点的路径的条数。注:象棋中马走“日”。

输入格式

输入 44 个整数,nnmmc_xcxc_ycy,分别表示 BB 点的横纵坐标和 CC 点的横纵坐标。

输出格式

输出一个整数,代表从 AA 点走到 BB 点的所有路径数。

样例输入

5 5 2 4

样例输出

14


思路 :将不能走的点储存起来 即马的控制点和马的那个点置为不可走点 到不可走点的路径数为0; 然后利用递推 到达 i j点 只能从i-1 j 点 或者 i j-1点过来 即要不从左边过来 要不从上面过来.

#include 
#include 
#define N 30
using namespace std;
long long vis[N][N], a[N][N], end_x, end_y, cx, cy;//vis 存储可行点 a储存起点到ij的路径数 star_x star_y 代表起点
int Go[8][2] = {{-1,2}, {-2,1}, {-2,-1}, {-1,-2}, {1,-2}, {2,-1}, {2,1}, {1,2}};
void fun()
{
	memset(vis,0,sizeof(vis));//全部置0 默认都可以走
	a[cx][cy] = 0;//到马的控制点的路径为0; 
	vis[cx][cy] = 1;
	for(int i = 0; i<8; i++)
	{
		int tmp_x = cx + Go[i][0];
		int tmp_y = cy + Go[i][1];
		if(tmp_x>=0 && tmp_x<=end_x && tmp_y>=0 && tmp_y<=end_y)
		{
			vis[tmp_x][tmp_y] = 1;
			a[tmp_x][tmp_y] = 0;
		}
	}
} 
int main()
{
	memset(a,0,sizeof(a));
	cin>> end_x >> end_y >> cx >> cy;
	fun();
	a[0][0] = 1;
	for(int i = 0; i<=end_x; i++)
	{
		for(int j = 0; j<=end_y; j++)
		{
			if(vis[i][j] || (i ==0 && j ==0))
			continue;
			if(i != 0 )
			a[i][j] += a[i-1][j];
			if(j != 0)
			a[i][j] += a[i][j-1];
		}
	}
	cout<

你可能感兴趣的:(计蒜客)