第二周共进行了5个实验,考察的内容主要是广度优先搜索的实现、map映射容器的使用、输入字符的格式转化与统计输出。
2.1走迷宫问题的求解
利用广度优先搜索进行迷宫路径的寻找
题目要求:
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜走。要求编程序找出从左上角到右下角的最短路线。
输入样例:
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
输出样例
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
算法:利用广度优先搜索
说明:定义坐标的结构体,有三个元素,分别为 横坐标 纵坐标 其上一个节点在队列中的位置
结构:两个5*5数组存储图与节点的访问情况;队列存储路径
输出:输出过程利用了递归函数,当有前驱节点时,对前驱节点进行访问
移动:在过程中,节点的移动有四个方向
判断:当节点移动后满足边界的判断条件时,将节点进行入队
节点中 previous为此时首节点head数,即首节点的位置数
#include<stdio.h>
struct node
{
int x; //x坐标
int y; //y坐标
int previous; //来到此点的出发点
};
int book[6][6]; //用来记录点是否访问过
int map[6][6]; //记录图
struct node queue[20]; //存储路径的队列
void print(struct node a) //实现路径输出的函数
{
if(a.previous==-1)
{
printf("(%d, %d)\n",a.x,a.y);
return ;
}
else
{
print(queue[a.previous]);
printf("(%d, %d)\n",a.x,a.y);
}
}
int main()
{
int i,j,k,m,n,x,y;
int head,tail;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
scanf("%d",&map[i][j]);
}
}
head=0; //初始时,队列的头节点与尾节点均为 0 号位置
tail=0;
queue[tail].x=0; //将迷宫的起点压入队列
queue[tail].y=0;
queue[tail].previous=-1;
book[0][0]=1;
tail++;
while(head<tail) //当队列为空时跳出,说明搜索没有找到可行路径
{
int next[4][2]={
{
0,1},{
0,-1},{
1,0},{
-1,0}}; //定义出四个方向
int flag=0;
for(i=0;i<4;i++) //从当前点往四周探索
{
int nextx=queue[head].x+next[i][0];
int nexty=queue[head].y+next[i][1]; //实现移动
if(nextx<0||nextx>4||nexty<0||nexty>4) //超出了边界则跳出
{
continue;
}
if(book[nextx][nexty]==0&&map[nextx][nexty]==0) //当点未被访问过且是可行点才入队
{
book[nextx][nexty]=1;
queue[tail].x=nextx;
queue[tail].y=nexty;
queue[tail].previous=head;
tail++;
}
if(nextx==4&&nexty==4) //到达了目的地,毫无疑问地跳出结束循环
{
flag=1;
break;
}
}
if(flag) //到达目的地后调用函数输出路径
{
print(queue[tail-1]);
break;
}
head++; //出队,head 代表当前进行广度优先遍历入队的节点在队列中位置
}
return 0;
}
2.1走迷宫问题解法二
// 利用 map 映射的方法解决走迷宫问题
#include <iostream>
#include <queue>
#include <map>
#include <stdio.h>
using namespace std;
//由于map函数会自动进行排序,因而结构体中应重载运算符 "<"
struct node
{
int x;
int y;
node() {
}
node(int _x,int _y) {
x=_x;y=_y;}; //带参构造节点
bool operator < (const node &b)const
{
return x == b.x ? y<b.y : x<b.x;
}
//节点向 4个方向进行移动的函数
node up()
{
node c;
c.x=x;
c.y=y+1;
return c;
}
node down()
{
node c;
c.x=x;
c.y=y+1;
return c;
}
node left()
{
node c;
c.x=x-1;
c.y=y;
return c;
}
node right()
{
node c;
c.x=x+1;
c.y=y;
return c;
}
};
map<node,node> previous; //用于表明与该节点相连的上一个节点
map<node,bool> book; //用于表明该节点是否被标记过
queue<node> q;
void print(node t)
{
if(previous.find(t)!=previous.end())
{