专题一 简单搜索 Problem K

题目链接:http://poj.org/problem?id=3984

题目大意:给定一个5*5的迷宫,其中有的点可走,有的点不可走,问从左上角到右下角所需要的最短步数。

     并记录下该最短路径的整个过程。

解题思路:bfs搜索

     由于这道题需要将路径打印出来,所以用一个结构体描述一点时,不仅需要记录该点的横纵坐标,还需要记录该点的上一个节点的编号。

     从队首取出一点,向4个方向开始搜索,如果满足条件,将该点标记为走过,放入队尾,此时还要记录它的上一个点(head-1)。

     防止搜索越界。output函数并不打印起点和终点。

代码如下:

 1 #include<cstdio>
 2 #include<cstring>
 3
 4 int maze[5][5];//描述迷宫
 5 struct Point
 6 {
 7     int x,y,pre;//描述迷宫中的一点,因为要打印路径,所有需要记录下来该点的上一个节点
 8 };
 9 Point Queue[50];//模拟队列实现过程
10 bool vis[5][5];//标记迷宫中的点是否走过
11
12 void output(int i)//该函数不打印起点(0,0)和终点(4,4)
13 {
14     if(Queue[i].pre!=-1)//递归找出每点的上一个点,并输出其坐标
15     {
16         output(Queue[i].pre);
17         printf("(%d, %d)\n",Queue[i].x,Queue[i].y);
18     }
19 }
20
21 void bfs()
22 {
23     memset(vis,0,sizeof(vis));//初始化标记为均未走过
24
25     int head=0,tail=1;//队首,队尾
26     //描述队首
27     Queue[0].x=Queue[0].y=0;
28     Queue[0].pre=-1;
29     vis[0][0]=1;
30
31     while(head<tail)
32     {
33         Point p=Queue[head++];//从队首取出一点,抛弃
34
35         if(p.x==4 && p.y==4) output(p.pre);//若该点是终点,则从它的上一点开始打印,直至终点
36
37         //判断该点是否走过,是否可走,是否处于迷宫中
38         if(p.x+1>=0 && p.x+1<=4 && maze[p.x+1][p.y]==0 && vis[p.x+1][p.y]==0)//向东
39         {
40             vis[p.x+1][p.y]=1;//标记走过
41             Queue[tail].pre=head-1;//因为队首点已经向下移了一格,所以该点的上一点是此时的队首-1
42             Queue[tail].x=p.x+1;//将该点放在队尾
43             Queue[tail++].y=p.y;//将该点放在队尾
44         }
45         if(p.x-1>=0 && p.x-1<=4 && maze[p.x-1][p.y]==0 && vis[p.x-1][p.y]==0)//向西
46         {
47             vis[p.x-1][p.y]=1;
48             Queue[tail].pre=head-1;
49             Queue[tail].x=p.x-1;
50             Queue[tail++].y=p.y;
51         }
52         if(p.y+1>=0 && p.y+1<=4 && maze[p.x][p.y+1]==0 && vis[p.x][p.y+1]==0)//向南
53         {
54             vis[p.x][p.y+1]=1;
55             Queue[tail].pre=head-1;
56             Queue[tail].x=p.x;
57             Queue[tail++].y=p.y+1;
58         }
59         if(p.y-1>=0 && p.y-1<=4 && maze[p.x][p.y-1]==0 && vis[p.x][p.y-1]==0)//向北
60         {
61             vis[p.x][p.y-1]=1;
62             Queue[tail].pre=head-1;
63             Queue[tail].x=p.x;
64             Queue[tail++].y=p.y-1;
65         }
66     }
67 }
68
69 int main()
70 {
71     for(int i=0;i<5;i++)//读入迷宫
72     {
73         for(int j=0;j<5;j++)
74         {
75             scanf("%d",&maze[i][j]);
76         }
77     }
78     printf("(0, 0)\n");
79     bfs();
80     printf("(4, 4)\n");
81     return 0;
82 }

时间: 2024-10-03 16:40:26

专题一 简单搜索 Problem K的相关文章

专题一 简单搜索 Problem A

题目链接:http://poj.org/problem?id=1321 题目大意和N皇后类似,只不过可能出现K<N的情况. 按照行的顺序进行深搜,如果当前行可以放置棋子,则换下一行进行搜索. 用一个二维数组描述棋盘,一个一维数组标记此列是否走过. 1 #include<cstdio> 2 #include<cstdlib> 3 4 const int MAXN=8; 5 char m[MAXN][MAXN]; //记录棋盘 6 int vis[MAXN]; //标记每一列是否

专题一 简单搜索 Problem B

题目链接:http://poj.org/problem?id=2251 题目大意:三维迷宫求两点间最短路. 解题思路:bfs搜索. 用一个三维数组maze记录迷宫的每一点是否可走. 用一个三维数组标记每一点是否已经走过. 用一个一维数组模拟队列的实现过程. 将起点放在队首,然后向六个方向扩展,若可行,则把该点放在队首,并抛弃队首成员. 如果当前点为终点,则记录下此时花费的时间,并返回. 代码如下: 1 #include<cstdio> 2 #include<cstring> 3 #

专题一 简单搜索 Problem C

题目链接:http://poj.org/problem?id=3278 题目大意:一条线上,给定起点和终点,求最短路径. 从当前点有三种选择,向左走一步,向右走一步,横坐标变为2倍. 解题思路:bfs搜索 将起点放在队首.每次从起点拿出一点,然后向三个方向扩展.如果满足条件,放入队尾. 如果该点满足,则返回总的步数. 代码如下: 1 #include<cstdio> 2 #include<cstring> 3 #define MAXN 200020 4 5 int n,k; 6 s

专题一 简单搜索 Problem F

题目链接:http://poj.org/problem?id=3126 题目大意:给定两个素数(四位数),求从第一个数变换到第二个数所需要的最小次数. 变换:每次允许变换个位/十位/百位/千位的其中一个数字.且保证变换完以后该数字仍然是素数. 解题思路:bfs搜索 每次从队首取出一个元素,向40个方向扩展(实际上只有34个方向),若满足条件,将其放入队尾. 直到找到该点,则返回此时一共走过的所有步数. 代码如下: 1 #include<cstdio> 2 #include<cmath&g

专题一 简单搜索 Problem G

题目链接:http://poj.org/problem?id=3087 题目大意:给定三堆牌,前两堆数目均为c,第三堆数目为2*c. 给定洗牌规则,问经过多少次洗牌才能到达第三堆牌的状态.如果不可能到第三堆牌的状态,输出-1. 解题思路:bfs模拟. 用字符串描述牌的状态.用set来标记该字符串是否出现过,如果第二次出现,说明已经陷入了循环,不可能得到结果. 开始先把s1和s2洗完,步数加一,放进set.然后判断该状态是否满足,如果不满足,则将该牌按规则分开,再次洗牌. 直到洗完的牌的状态满足了

专题一 简单搜索 Problem L

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1241 题目大意:给定一个方格,有的点是‘@’,有的点是‘*’.若以一个‘@’为中心的3*3的矩阵中,其他‘@’和该‘@’属于同一区域. 求方格中一共有多少区域. 解题思路:dfs深搜 遍历每一个点,如果该点可以向深扩展,则分别向8个方向扩展,以此类推,直到递归结束. 递归结束后,区域数目加一,所以和该点有“关系”的点都被标记.然后判断其他可扩展的点. 代码如下: 1 #include<cstdio>

kuangbin带你飞专题一 简单搜索 题解

目录 [kuangbin带你飞]专题一 简单搜索 [kuangbin带你飞]专题一 简单搜索 总结:用时2天半终于把这个专题刷完了 对于最基础的dfs bfs 路径打印 状态转移也有了一点自己些微的理解 其实2天半可以压缩到1天半的 主要是自己太懒了...慢慢加油刷bin神的专题呀 从大二下学期开始学算法 一开始就知道这个专题 一开始对于这个专题里的所有问题感觉都好难啊..就直接放弃了 看lrj的书 现在看到这个专题还挺唏嘘的吧 突然觉得思维和想法也不是很难 果然是那个时候心不静&还是储量不够吗

专题一 简单搜索

本专题主要锻炼搜索的两大方法——bfs (宽度优先搜索)和 dfs (深度优先搜索) ===================================华丽的分割线======================================= 一.bfs——宽度优先搜索 bfs主要运用于搜索中求最短时间的问题,搜索过程中一般需要运用 queue 的操作.具体的操作如下: 1.首先需要将 队列 和 visit数组 清空.(这一点很重要!!!) 2.然后将起点信息 push 进队列,标记为vis

[kuangbin带你飞]专题一 简单搜索 - K - 迷宫问题

1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 struct node 8 { 9 int x; 10 int y; 11 int s; 12 }; 13 int g[10][10]; 14 int d[4][2]={{1,0},{-1,0},{0