【信奥一本通刷题记录】1314:【例3.6】过河卒(Noip2002)

【题目描述】

棋盘上 A A A点有一个过河卒,需要走到目标 B B B点。卒行走的规则:可以向下、或者向右。同时在棋盘上的某一点有一个对方的马(如 C C C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点,如下图中的 C C C点和 P 1 , … … , P 8 P1,……,P8 P1……P8,卒不能通过对方马的控制点。棋盘用坐标表示, A A A ( 0 , 0 ) (0,0) (0,0) B B B ( n , m ) (n, m) (n,m) ( n , m n,m n,m为不超过 20 20 20的整数),同样马的位置坐标是需要给出的, C ≠ A C≠A C=A C ≠ B C≠B C=B。现在要求你计算出卒从 A A A点能够到达 B B B点的路径的条数。

过河卒问题图片

【输入】

给出 n n n m m m C C C点的坐标。

【输出】

A A A点能够到达 B B B点的路径的条数。

【解题思路】

  1. 定义二值化地图 a [ 100 ] [ 100 ] a[100][100] a[100][100],马的控制位置一共 9 9 9个点,设置为 1 1 1,代表不可通行节点;其余均为 0 0 0,代表可以通行。
  2. 定义路径条数存储的地图 b [ 100 ] [ 100 ] b[100][100] b[100][100],其中每个数值均为地图中该点到 A A A点的可行路径条数。为了防止到 b [ − 1 ] [ 0 ] b[-1][0] b[1][0]这种越界的情况,把输入 n , m , C x , C y n,m,Cx,Cy n,m,Cx,Cy + 1 +1 +1处理。
  3. 初始化 b [ 1 ] [ 1 ] b[1][1] b[1][1] 1 1 1,即 A A A点到 A A A点有一条路径(假设情况),从而后边就可以通过递推公式 b [ i ] [ j ] = b [ i − 1 ] [ j ] + b [ i ] [ j − 1 ] b[i][j]=b[i-1][j]+b[i][j-1] b[i][j]=b[i1][j]+b[i][j1] 得到,注意如果遇到不可通行节点,则 b [ i ] [ j ] = 0 b[i][j]=0 b[i][j]=0
  4. 最后输出 b [ n ] [ m ] b[n][m] b[n][m]即为 B B B点到 A A A点的可通行路径条数(并非 b [ n − 1 ] [ m − 1 ] b[n-1][m-1] b[n1][m1],因为我们对 n , m n,m n,m已经进行过 + 1 +1 +1操作了)。

【解题代码】

#include <bits/stdc++.h>
using namespace std;

bool a[100][100];
long long b[100][100];

int main() {
	int n,m,Cx,Cy;
	cin >> n >> m >> Cx >> Cy;
	n += 1, m += 1, Cx += 1, Cy += 1; //所有坐标+1,防止越界
	//设置马的控制位置全为1
	a[Cx][Cy] = 1;
	a[Cx - 1][Cy + 2] = 1;
	a[Cx - 1][Cy - 2] = 1;
	a[Cx - 2][Cy + 1] = 1;
	a[Cx - 2][Cy - 1] = 1;
	a[Cx + 1][Cy + 2] = 1;
	a[Cx + 1][Cy - 2] = 1;
	a[Cx + 2][Cy + 1] = 1;
	a[Cx + 2][Cy - 1] = 1;
	//设置初始位置为1,进行动态规划递推
	b[1][1] = 1;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			if (i == 1 && j == 1) {
				j++;
			}
			if (a[i][j] == 0) {
				b[i][j] = b[i - 1][j] + b[i][j - 1];
			}
		}
	}
	cout << b[n][m];
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值