DP:过河卒
题目描述
棋盘上 AAA 点有一个过河卒,需要走到目标 BBB 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 CCC 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,AAA 点 (0,0)(0, 0)(0,0)、BBB 点 (n,m)(n, m)(n,m),同样马的位置坐标是需要给出的。
现在要求你计算出卒从 AAA 点能够到达 BBB 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式
一行四个正整数,分别表示 BBB 点坐标和马的坐标。
输出格式
一个整数,表示所有的路径条数。
输入输出样例
6 6 3 3
6
说明/提示
对于 100%100 \%100% 的数据,1≤n,m≤201 \le n, m \le 201≤n,m≤20,0≤0 \le0≤ 马的坐标 ≤20\le 20≤20。
本人也还是小白,本题的图以及方阵都来自洛谷,仅仅是用于好理解思路,做题,没有其他用途。
主要思路:不难发现每一个格子拥有的路径数(即走不同路径经过这个格子的次数),都是左边和上边格子拥有路径数之和。就所给样例而言:M表示马,A,B表示进出口
A 0 0 0 0 0 0 0 0 X 0 X 0 0 0 X 0 0 0 X 0 0 0 0 M 0 0 0 0 X 0 0 0 X 0 0 0 X 0 X 0 0 0 0 0 0 0 0 B
然后画出这种情况各点拥有路径情况:
1 1 1 1 1 1 1 1 2 X 1 X 1 2 1 X 0 1 1 X 2 1 1 1 M 1 1 3 1 X 1 1 0 X 3 1 1 X 1 X 0 3 1 2 2 3 3 3 6
很容易就发现规律,每个格子拥有的路径数就是左边和上边格子拥有的路径数之和,对于马的控制区,我们也进行访问,然后判断如果是马的控制区我们至于要把这个点设为0即可。
但是为了防止数组访问越界,我们可以给原有的方阵左边和上边加一列一行0,如图:
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 2 X 1 X 1 2 0 1 X 0 1 1 X 2 0 1 1 1 M 1 1 3 0 1 X 1 1 0 X 3 0 1 1 X 1 X 0 3 0 1 2 2 3 3 3 6
这样之后我们就可以轻松的访问了。
初状态: a[1][0] = 1 ,当然 a[0][1] = 1 也没有问题。
递推: a[i][j] = a[i - 1][j] + a[i][j - 1]
上边是核心思路。
因为需要判断马的控制区,所以我们可以直接做一个表:
void bj(int mmx, int mmy) //被马控制的格子 { map[mmx][mmy] = 1; map[mmx - 2][mmy - 1] = 1; map[mmx - 1][mmy - 2] = 1; map[mmx + 1][mmy - 2] = 1; map[mmx + 2][mmy - 1] = 1; map[mmx + 2][mmy + 1] = 1; map[mmx + 1][mmy + 2] = 1; map[mmx - 1][mmy + 2] = 1; map[mmx - 2][mmy + 1] = 1; }
所以这个题的核心代码就生成啦。
for (int i = 1; i <= x + 1; i++) { for (int j = 1; j <= y + 1; j++) { a[i][j] = a[i - 1][j] + a[i][j - 1]; if (map[i - 1][j - 1]) { a[i][j] = 0; } } }
至于为什么判断
map[i-1][j-1]而不是map[i][j]
那是因为我们给整个数组加了一行一列,所以我们当前访问的i,j就是原数组的i-1,j-1。
所以最终代码:
1 #include<iostream> 2 #include<algorithm> 3 4 using namespace std; 5 6 unsigned long long x, y, mx, my; 7 long long a[25][25], map[25][25]; //用来标记 8 9 void bj(int mmx, int mmy) //被马控制的格子 10 { 11 map[mmx][mmy] = 1; 12 map[mmx - 2][mmy - 1] = 1; 13 map[mmx - 1][mmy - 2] = 1; 14 map[mmx + 1][mmy - 2] = 1; 15 map[mmx + 2][mmy - 1] = 1; 16 map[mmx + 2][mmy + 1] = 1; 17 map[mmx + 1][mmy + 2] = 1; 18 map[mmx - 1][mmy + 2] = 1; 19 map[mmx - 2][mmy + 1] = 1; 20 } 21 22 int main() 23 { 24 a[1][0] = 1; 25 cin >> x >> y >> mx >> my; 26 27 bj(mx, my); //调用标记函数 28 for (int i = 1; i <= x + 1; i++) 29 { 30 for (int j = 1; j <= y + 1; j++) 31 { 32 a[i][j] = a[i - 1][j] + a[i][j - 1]; 33 if (map[i - 1][j - 1]) 34 { 35 a[i][j] = 0; 36 } 37 } 38 } 39 40 cout << a[x + 1][y + 1]; 41 return 0; 42 }
原文地址:https://www.cnblogs.com/ZhengLijie/p/12720819.html
- pc端与移动端的事件总结
- 技术分享 | Apache Kafka下载与安装启动
- JavaScript数组操作总结
- 初识Shiro
- 在网页里点击链接,直接打开app的方法
- 常用算法比较,js实现
- Exploiting Jolokia Agent with Java EE Servers
- AngularJS数据源的多种获取方式汇总
- 跨站的艺术-XSS入门与介绍
- 堆排序
- 两个元素定位,要求子元素垂直居中
- 在Spring Boot框架下使用WebSocket实现消息推送
- Linux上安装Zookeeper以及一些注意事项
- Nginx+Tomcat搭建集群,Spring Session+Redis实现Session共享
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- elasticsearch-快速入门
- 数据库技术:JDBC,预处理对象,事务控制
- elasticsearch-DSL高级查询语法
- 数据库技术:XML
- 利用logstash将mysql多表数据增量同步到es
- 纯CSS实现自定义单选框和复选框
- 基于Linux安装Mysql5.7
- 纯CSS实现iOS风格打开关闭选择框
- 算法基础:递归
- ELK日志收集原理+es集群+elk搭建+本地目录文件读取,搭建分布式日志收集系统
- 什么是JavaScript 的闭包???
- es集群+elk搭建+kafka搭建分布式日志收集系统
- 设计模式(2)[JS版]---JavaScript如何实现单例模式?
- 算法基础:分治
- 黑客帝国中代码雨如何实现?用 canvas 轻松实现代码雨炫酷效果!