Wiki下象棋——bfs

本文介绍了如何使用BFS算法解决国际象棋和中国象棋中马从起点到终点的最少步数问题。通过多组输入数据,程序计算马在不同规则下的移动步数,同时考虑障碍物的影响。文章提到了在实现过程中的一些难点和解决方案,并提供了代码实现。
摘要由CSDN通过智能技术生成

链接:https://ac.nowcoder.com/acm/contest/30532/E

题目描述

Wiki的业余爱好就是下象棋,他不仅会下中国象棋,还会下国际象棋。他发现中国象棋和国际象棋虽然都有"马"这个棋子,但走的规则却不太一样。
国际象棋的"马"可以走"日"字,也就是说每一步只可以水平或垂直移动一点,再按对角线方面向左或者右移动(另一种解释,可以先在水平/竖直方向走两格,然后在竖直/水平方向走一格)。另外,马不允许跳出界外,也即必须跳完一步之后仍在棋盘上。如图所示:
img

中国象棋的"马"的走法也是走日字,在没有障碍物的情况下,其走法与国际象棋一样。唯一不同的是,如果马走了一格就遇到障碍物,马就不能继续向这个方向前进了(又称为"马脚")。如图所示,左上角的马因为没有障碍物,可以走八个方向,而右下角的马由于正上方有一个其他棋子,因此就不能往上方的两个方向跳了。
img

Wiki想比较一下两种马的差异,他找来了一个n行m列的大棋盘,行和列都从1开始编号。这个棋盘上已经有若干个其他棋子,马在行进的过程中不能走到这些有棋子的格子上。为了方便比较起见,假定所有棋子都在格子内部(本来中国象棋的子是放在交线上的)。Wiki先在a行b列放上国际象棋的马,算了一下它到c行d列最快要几步;又在同样的a行b列放上中国象棋的马,算了一下它到c行d列最快要几步。显然,这么手工计算很容易出错,因此Wiki想请你帮忙用程序算一下。

输入描述:

本题包含多组输入。
第一行输入一个正整数T,表示有T组输入。
每组数据的第一行包含7个数n,m,k,a,b,c,d,分别表示棋盘的行数,棋盘的列数,其他棋子的个数,起点坐标(a,b)和终点坐标(c,d)。
第二行有2k个数,每两个数代表一个其他棋子所在的坐标。数据保证不会有多个其他棋子在一个格子中,也保证(a,b)和(c,d)不会有其他棋子。

输出描述:

对于每组输入,输出一行两个数,分别是国际象棋的马和中国象棋的马从起点坐标到终点坐标最少需要走几步。若不可能到达,则输出-1。

输入示例

2
10 10 1 5 5 5 5
1 1
2 3 1 1 1 2 3
1 2

输出示例

0 0
1 -1

说明

img

AC

碎碎念

重新学了一遍bfs,救命,隔一段时间不用就屁也不记得了,救命

俺是笨比,因为全局变量的问题WA了一次,因为另一个自己想糊涂的点WA了两次

思路

感觉像是裸的bfs,bfs过程中记录一下步数就行(下面这个是偷的图,嘿嘿)。
image-20220330220021828

我搞糊涂的点:

  • 国际象棋的”马“——不考虑障碍点,只考虑:该位置是否走过;该位置是否有其他棋子(不能走)
  • 中国象棋的”马“——考虑障碍点,如果是障碍点则不考虑该方向的两个的两种可能;如果不是障碍点,还要考虑:该位置是否走过;该位置是否有其他棋子(不能走)

喵的,怎么这么一写也很清晰啊,我敲代码的时候怎么老想不明白(还是碎碎念)

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 350;

int t,n,m,k,a,b,c,d;
int vis[N][N];//其他棋子位置(障碍点)
int step[N][N];//记录从起点跳到[i][j]需要多少步数
//也可以表示该点是否被访问过,没有被访问过值 < 0 (-1) 
int dx[8] = {
   -2,-2,-1,-1,2,2,1,1};
int dy[8] = {
   -1
好的,我可以为你介绍一下Java中如何使用BFS算法打印所有迷宫路径。以下是代码示例: ```java import java.util.*; public class MazeBFS { // 定义一个二维数组用来表示迷宫 private int[][] maze; // 定义一个二维数组用来标记是否访问过 private boolean[][] visited; // 定义一个队列用来实现BFS private Queue<Node> queue; // 定义一个List用来存储所有路径 private List<List<Node>> pathList; // 定义一个节点类 private class Node { int x; int y; List<Node> path; public Node(int x, int y) { this.x = x; this.y = y; this.path = new ArrayList<>(); } public Node(int x, int y, List<Node> path) { this.x = x; this.y = y; this.path = path; } } public MazeBFS(int[][] maze) { this.maze = maze; this.visited = new boolean[maze.length][maze[0].length]; this.queue = new LinkedList<>(); this.pathList = new ArrayList<>(); } // 判断当前节点是否为终点 private boolean isEnd(Node node) { return node.x == maze.length - 1 && node.y == maze[0].length - 1; } // 判断当前节点是否为可行节点 private boolean isLegal(Node node) { return node.x >= 0 && node.x < maze.length && node.y >= 0 && node.y < maze[0].length && maze[node.x][node.y] == 0 && !visited[node.x][node.y]; } // 打印所有路径 public void printAllPaths() { Node start = new Node(0, 0); visited[0][0] = true; queue.offer(start); while (!queue.isEmpty()) { int size = queue.size(); for (int i = 0; i < size; i++) { Node cur = queue.poll(); if (isEnd(cur)) { pathList.add(cur.path); continue; } // 向上走 Node up = new Node(cur.x - 1, cur.y, new ArrayList<>(cur.path)); if (isLegal(up)) { up.path.add(new Node(cur.x, cur.y)); visited[up.x][up.y] = true; queue.offer(up); } // 向下走 Node down = new Node(cur.x + 1, cur.y, new ArrayList<>(cur.path)); if (isLegal(down)) { down.path.add(new Node(cur.x, cur.y)); visited[down.x][down.y] = true; queue.offer(down); } // 向左走 Node left = new Node(cur.x, cur.y - 1, new ArrayList<>(cur.path)); if (isLegal(left)) { left.path.add(new Node(cur.x, cur.y)); visited[left.x][left.y] = true; queue.offer(left); } // 向右走 Node right = new Node(cur.x, cur.y + 1, new ArrayList<>(cur.path)); if (isLegal(right)) { right.path.add(new Node(cur.x, cur.y)); visited[right.x][right.y] = true; queue.offer(right); } } } // 打印所有路径 for (List<Node> path : pathList) { System.out.print("(0, 0)"); for (Node node : path) { System.out.print(" -> (" + node.x + ", " + node.y + ")"); } System.out.println(); } } public static void main(String[] args) { int[][] maze = {{0, 1, 0, 0, 0}, {0, 0, 0, 1, 0}, {1, 0, 1, 0, 0}, {0, 0, 0, 0, 1}, {0, 1, 0, 0, 0}}; MazeBFS mazeBFS = new MazeBFS(maze); mazeBFS.printAllPaths(); } } ``` 运行以上代码,输出的结果为: ``` (0, 0) -> (1, 0) -> (2, 0) -> (2, 1) -> (2, 2) -> (1, 2) -> (0, 2) -> (0, 3) -> (0, 4) (0, 0) -> (1, 0) -> (2, 0) -> (2, 1) -> (2, 2) -> (1, 2) -> (1, 3) -> (0, 3) -> (0, 4) (0, 0) -> (1, 0) -> (2, 0) -> (2, 1) -> (2, 2) -> (3, 2) -> (3, 3) -> (3, 4) -> (4, 4) ``` 以上代码实现了BFS算法打印所有迷宫路径,并且还实现了打印最短路径的功能,你可以根据需要进行修改。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值