P1825 [USACO11OPEN] Corn Maze S 广度优先搜索

2024-02-01 16:04

本文主要是介绍P1825 [USACO11OPEN] Corn Maze S 广度优先搜索,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 题目链接
  • 题目描述
  • 解题思路
  • 代码实现
  • 总结


题目链接

链接: P1825 [USACO11OPEN] Corn Maze S

题目描述

在这里插入图片描述

解题思路

这道题目是一个典型的迷宫问题,我们需要找出从起点到终点的最短路径。解决这类问题的常用方法是使用广度优先搜索(BFS)算法。

首先,我们需要读取迷宫的输入,并确定起点的位置。然后,我们可以使用一个队列来存储每一步的状态,其中每个状态记录了当前位置的坐标和到达该位置的步数。我们还需要一个布尔数组来标记已经访问过的位置,以避免重复访问。

在搜索过程中,我们从起点出发,将起点的状态加入队列,并标记起点为已访问。然后,我们不断从队列中取出状态,并根据当前位置的上下左右四个方向进行扩展。如果扩展得到的位置是墙壁或已经访问过的位置,则跳过该位置。如果扩展得到的位置是传送门,则查找相应传送门的另一端位置,并将另一端位置的状态加入队列,步数加1。如果扩展得到的位置是空地,则将该位置的状态加入队列,步数加1,并标记该位置为已访问。

当遇到传送门时,我们需要查找相应传送门的另一端位置,并将另一端位置的状态加入队列,步数加1。

具体而言,我们可以在搜索过程中,判断当前位置是否为传送门(即位置上的字符为大写字母)。如果是传送门,我们可以调用一个函数 cs(char c, int x, int y) 来查找传送门 c 的另一端位置。该函数会遍历迷宫中的其他位置,找到与给定传送门对应的传送门位置。

在函数 cs 中,我们可以使用两层循环遍历迷宫的每个位置:

对于每个位置 (i, j),如果它不是当前位置 (x, y),并且字符为传送门 c,则返回位置 (i, j)。
如果 cs 函数找到了与传送门 c 对应的位置 (i, j),我们可以将该位置的状态 (i, j, t.step + 1) 加入队列,步数加1。其中 t.step + 1 表示到达 (i, j) 位置需要的步数。

需要注意的是,如果 cs 函数没有找到与传送门 c 对应的位置,我们应该返回一个特殊的标记,例如 {-1, -1},表示未找到对应的传送门。

通过在搜索过程中处理传送门,我们可以在搜索最短路径时,考虑迷宫中的传送功能,从而得到正确的结果。

我们在搜索过程中不断扩展状态,直到队列为空或者找到等号位置。如果最终找到等号位置,则输出到达该位置的步数;否则,输出-1表示无解。

代码实现

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=310;
char a[N][N];
bool st[N][N];
struct node{int x;int y;int step;
}q[N*N];
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
int n,m,ans;
PII cs(char c,int x,int y)
{for(int i=1;i<n-2;i++)for(int j=1;j<m-2;j++)if(i!=x&&a[i][j]==c) return {i,j};
}
void bfs(int x,int y)
{int hh=0,tt=0;q[0]={x,y,0}; st[x][y]=true;while(hh<=tt){node t=q[hh++];if(a[t.x][t.y]=='='){cout<<t.step<<endl;return;} for(int i=0;i<4;i++){int nx=t.x+dx[i];int ny=t.y+dy[i];if(a[nx][ny]=='#'||st[nx][ny]) continue;if ( ny < m && a[nx][ny] != '#' && !st[nx][ny]) {st[nx][ny] = true;if (a[nx][ny] >= 'A' && a[nx][ny] <= 'Z') {// 寻找对应传送门的位置for (int j = 1; j < n-1; j++) {for (int k = 1; k < m-1; k++) {if (a[j][k] == a[nx][ny] && (j != nx || k != ny)) {q[++tt]={j,k,t.step+1};break;}}}} else {q[++tt]={nx, ny, t.step + 1};}}}}
}
int main()
{int bx,by;//起始点 cin>>n>>m;for(int i=0;i<n;i++)for(int j=0;j<m;j++){cin>>a[i][j];if(a[i][j]=='@') bx=i,by=j;} 	bfs(bx,by);return 0;
}

总结

总结起来,解决这道题目的关键思路是使用BFS算法进行图的遍历,通过不断扩展状态来搜索迷宫中的最短路径。通过使用队列和标记数组,我们可以确保每个位置只被访问一次,并且在找到目标位置时能够得到最短路径的步数。
通过解决这道题目,我们学到了以下几个关键点:

  1. 广度优先搜索(BFS)算法:这道题目的解题思路主要基于广度优先搜索算法。BFS是一种遍历图的算法,它从起点开始,逐层扩展搜索,直到找到目标位置。在解决迷宫问题中,BFS可以帮助我们找到最短路径。

  2. 处理传送门:题目要求我们要处理迷宫中的传送门。通过编写一个函数来查找传送门的另一端位置,我们可以在搜索过程中正确处理传送门带来的跳跃和路径缩短。

  3. 队列和标记数组的应用:使用队列和标记数组可以帮助我们进行状态扩展和避免重复访问。队列可以用来存储每一步的状态,并按照先进先出的顺序进行扩展,确保每个位置只被访问一次。标记数组用于标记已经访问过的位置,以避免重复访问。

在思考这道题目时,我们需要考虑以下几个方面:

  1. 思考问题的复杂度:对于某些复杂的问题,我们需要思考如何降低问题解决的复杂度。在这道题目中,我们使用了广度优先搜索算法,通过按层扩展的方式遍历迷宫,从而找到最短路径。这种方式能够确保我们找到的路径是最短的。

  2. 掌握基本的数据结构和算法:解决这道题目需要我们熟悉广度优先搜索算法以及队列和标记数组的应用。理解并灵活运用这些基本的数据结构和算法可以帮助我们解决更复杂的问题。

  3. 注重程序的可读性和可维护性:在解决问题的过程中,我们要注意编写具有良好可读性和可维护性的代码。合理的代码结构和注释可以使我们更好地理解和调试代码,并且在以后需要修改或扩展代码时能够更加容易。

总而言之,通过这道题目我们不仅学习了基本的算法思想和数据结构,还培养了解决问题的思维和优化思考的能力。同时,我们也明确了代码可读性和可维护性在开发过程中的重要性。

这篇关于P1825 [USACO11OPEN] Corn Maze S 广度优先搜索的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/667739

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

hdu1180(广搜+优先队列)

此题要求最少到达目标点T的最短时间,所以我选择了广度优先搜索,并且要用到优先队列。 另外此题注意点较多,比如说可以在某个点停留,我wa了好多两次,就是因为忽略了这一点,然后参考了大神的思想,然后经过反复修改才AC的 这是我的代码 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<

poj 3190 优先队列+贪心

题意: 有n头牛,分别给他们挤奶的时间。 然后每头牛挤奶的时候都要在一个stall里面,并且每个stall每次只能占用一头牛。 问最少需要多少个stall,并输出每头牛所在的stall。 e.g 样例: INPUT: 51 102 43 65 84 7 OUTPUT: 412324 HINT: Explanation of the s

poj 2431 poj 3253 优先队列的运用

poj 2431: 题意: 一条路起点为0, 终点为l。 卡车初始时在0点,并且有p升油,假设油箱无限大。 给n个加油站,每个加油站距离终点 l 距离为 x[i],可以加的油量为fuel[i]。 问最少加几次油可以到达终点,若不能到达,输出-1。 解析: 《挑战程序设计竞赛》: “在卡车开往终点的途中,只有在加油站才可以加油。但是,如果认为“在到达加油站i时,就获得了一

hdu 4517 floyd+记忆化搜索

题意: 有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。 访问每个景点需要时间cost_i,每个景点的访问价值为value_i。 点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。 走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。 现在求,从起点出发,到达终点,在时间限制内,能得到的最大

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

hdu4277搜索

给你n个有长度的线段,问如果用上所有的线段来拼1个三角形,最多能拼出多少种不同的? import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

POJ2010 贪心优先队列

c头牛,需要选n头(奇数);学校总共有f的资金, 每头牛分数score和学费cost,问合法招生方案中,中间分数(即排名第(n+1)/2)最高的是多少。 n头牛按照先score后cost从小到大排序; 枚举中间score的牛,  预处理左边与右边的最小花费和。 预处理直接优先队列贪心 public class Main {public static voi

深度优先(DFS)和广度优先(BFS)——算法

深度优先 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访