P1002 [NOIP2002 普及组] 过河卒
题目描述
棋盘上 A 点有一个过河卒,需要走到目标 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示, 点 (0, 0)、B 点 (n, m),同样马的位置坐标是需要给出的。

现在要求你计算出卒从 A 点能够到达 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式
一行四个正整数,分别表示 点坐标和马的坐标。
输出格式
一个整数,表示所有的路径条数。
#include <iostream>
using namespace std;
long long f[25][25];
bool g[25][25];
// x1为棋盘长度 y1为棋盘宽度
// x2为马的横坐标 y2为马的纵坐标
// g数组记录该点是否可走 f数组记录路线
int main()
{
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
g[x2][y2] = 1;
//记录马的控制点
if (x2 > 1 and y2 != 0)
{
g[x2 - 2][y2 - 1] = 1;
} //这里>1与>=2是等效的,下同
if (x2 < 19 and y2 != 0)
{
g[x2 + 2][y2 - 1] = 1;
} //这里<19与<=18是等效的,下同
if (x2 > 1 and y2 != 20)
{
g[x2 - 2][y2 + 1] = 1;
}
if (x2 < 19 and y2 != 20)
{
g[x2 + 2][y2 + 1] = 1;
}
if (x2 != 0 and y2 > 1)
{
g[x2 - 1][y2 - 2] = 1;
}
if (x2 != 0 and y2 < 19)
{
g[x2 - 1][y2 + 2] = 1;
}
if (x2 != 20 and y2 > 1)
{
g[x2 + 1][y2 - 2] = 1;
}
if (x2 != 20 and y2 < 19)
{
g[x2 + 1][y2 + 2] = 1;
}
//递推过程
for (int i = 0; i <= x1; ++i)
{
for (int j = 0; j <= y1; ++j)
if (!g[i][j])
{ //该点没被马控制
if (i == 0 and j == 0) //递推边界1 f[0][0]=1
{
f[0][0] = 1;
}
else if (i == 0 and j > 0) //递推边界2,x=0时;
{
f[0][j] = f[0][j - 1];
}
else if (i > 0 and j == 0) //递推边界3,y=0时;
{
f[i][0] = f[i - 1][0];
}
else
{
f[i][j] = f[i - 1][j] + f[i][j - 1];
} //递推核心
}
}
//最终i循环到x1位置,j循环到y1位置(x1,y1)即为目标点)则f[x1][y1]就是答案
cout << f[x1][y1]; //
return 0;
}

浙公网安备 33010602011771号