AA 点有一个过河卒,需要走到目标 BB 点。卒行走规则:可以向下、或者向右。同时在棋盘上的任一点有一个对方的马(如上图的 CC 点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。例如上图 CC 点上的马可以控制 99 个点(图中的 P1,P2 \cdots P8P1,P2⋯P8 和 CC)。卒不能通过对方马的控制点。
棋盘用坐标表示,AA 点(00,00)、BB 点(nn,mm)、CC 点(c_xcx,c_ycy)(0 < c_x < n \leq 200<cx<n≤20,0 < c_y < m \leq 200<cy<m≤20)。现在要求你计算出过河卒从 AA 点能够到达 BB 点的路径的条数。注:象棋中马走“日”。
输入格式
输入 44 个整数,nn,mm,c_xcx,c_ycy,分别表示 BB 点的横纵坐标和 CC 点的横纵坐标。
输出格式
输出一个整数,代表从 AA 点走到 BB 点的所有路径数。
样例输入
5 5 2 4
样例输出
14
思路 :将不能走的点储存起来 即马的控制点和马的那个点置为不可走点 到不可走点的路径数为0; 然后利用递推 到达 i j点 只能从i-1 j 点 或者 i j-1点过来 即要不从左边过来 要不从上面过来.
#include <bits/stdc++.h>
#include <memory.h>
#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<<a[end_x][end_y];
return 0;
}