洛谷-P1002-[NOIP2002 普及组]-过河卒

[NOIP2002 普及组] 过河卒

题目描述

棋盘上 A A A 点有一个过河卒,需要走到目标 B B B 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 C C C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。

棋盘用坐标表示, A A A ( 0 , 0 ) (0, 0) (0,0) B B B ( n , m ) (n, m) (n,m),同样马的位置坐标是需要给出的。

洛谷-P1002-[NOIP2002 普及组]-过河卒_第1张图片

现在要求你计算出卒从 A A A 点能够到达 B B B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。

输入格式

一行四个正整数,分别表示 B B B 点坐标和马的坐标。

输出格式

一个整数,表示所有的路径条数。

样例 #1

样例输入 #1

6 6 3 3

样例输出 #1

6

提示

对于 100 % 100 \% 100% 的数据, 1 ≤ n , m ≤ 20 1 \le n, m \le 20 1n,m20 0 ≤ 0 \le 0 马的坐标 ≤ 20 \le 20 20

【题目来源】

NOIP 2002 普及组第四题

#include
using namespace std;
const int N = 35;
const int dx[8] = { 1,1,-1,-1,2,2,-2,-2 };
const int dy[8] = { 2,-2,2,-2,1,-1,1,-1 };

long long f[N][N] = { 0 };	//f[i][j] 代表从0,0到i,j的路线数量
int n, m, x, y;
bool vis[N][N];

int main() {
	cin >> n >> m >> x >> y;
	vis[0][0] = 1;	//标记入点
	vis[x][y] = 1;	//标记马的位置

	for (int i = 0; i < 8; i++) {	//标记马的控制点,记住防越界
		int xx = x + dx[i], yy = y + dy[i];
		if(xx >= 0 && xx <= n && yy >= 0 && yy <= m)
			vis[xx][yy] = 1;
	}

	f[0][0] = 1;	//把0,0点初始化为1

	for (int i = 0; i <= n; i++) {
		for (int j = 0; j <= m; j++) {	//要判断是否越界
			if (!vis[i][j]) {
				if (i - 1 < 0) {
					f[i][j] = f[i][j - 1];
				}else
				if (j - 1 < 0) {
					f[i][j] = f[i - 1][j];
				}
				else {
					f[i][j] = f[i - 1][j] + f[i][j - 1];//由于只能往下走或者往右走,所以为两个方向走过来的数量加起来
				}
			}
		}
	}

	cout << f[n][m];
	return 0;
}

你可能感兴趣的:(算法,数据结构,动态规划,c++)