7-1 迷宫寻路 (20分)
给定一个M行N列的迷宫图,其中 “0"表示可通路,“1"表示障碍物,无法通行。在迷宫中只允许在水平或上下四个方向的通路上行走,走过的位置不能重复走。
5行8列的迷宫如下:
0 1 1 1 0 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 0
0 1 1 1 0 1 1 0
1 0 0 0 0 0 0 0
则从左上角(1,1)至右下角(5,8)的最短路径为:
1,1–》2,1–》2,2–》2,3–》3,3–》3,4–》3,5–》4,5–》5,5–》5,6–》5,7–》5,8
题目保证每个迷宫最多只有一条最短路径。
请输出该条最短路径,如果不存在任何通路,则输出"NO FOUND”.
输入格式:
第一行,输入M和N值,表示迷宫行数和列数。
接着输入M行数值,其中,0表示通路,1表示障碍物。每列数值用空格符间隔。
接下来可能输入多组迷宫数据。
当输入M的值为-1时结束输入。
输出格式:
按行顺序输出路径的每个位置的行数和列数,如 x,y
如果不存在任何路径,则输出"NO FOUND”.
每组迷宫寻路结果用换行符间隔。
输入样例:
在这里给出一组迷宫。例如:

8 8
0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0
0 0 0 0 1 1 0 0
0 1 1 1 0 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 0
0 1 1 1 0 1 1 0
1 0 0 0 0 0 0 0
4 4
0 0 1 0
0 0 0 0
0 0 1 1
0 1 0 0
-1 -1

输出样例:
在这里给出相应的输出。例如:

1,1
2,1
3,1
4,1
5,1
5,2
5,3
6,3
6,4
6,5
7,5
8,5
8,6
8,7
8,8 NO FOUND

程序思路:
(1)从入口元素开始,判断它上下左右的邻边元素是否满足条件,如果满足条件就入队列;
(2)取队首元素并出队列。寻找其相邻未被访问的元素,将其如队列并标记元素的前驱节点为队首元素;
(3)重复步骤(2),直到队列为空(没有找到可行路径)或者找到了终点。最后从终点开始,根据节点的前驱节点找出一条最短的可行路径。
程序实现:

#include<bits/stdc++.h>
using namespace std;
/**
* Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,
* 由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。
* 这里说下map内部数据的组织,map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,
* 所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,
* 因为它没有小于号操作,insert等函数在编译的时候过不去,既然是没有‘<’,那我们自己重载小于操作符应该就可以了。
*/
struct site{
int x,y,k;
friend bool operator<(const struct site& a, const struct site& b) {
if (a.x < b.x ||
(a.x == b.x && a.y < b.y)) {
return true;
}
return false;
}
}p[100];//将到终点的路线逆向保存
int main(){
int m, move[4][2] = { {1,0} , {0,1} , {-1,0} , {0,-1} };//用二维数组分别表示下右上左
cin>>m;
while(m != -1) {
map<site,site> f;//用来记录前驱
int n,a[100][100],flag = 1;
struct site temp;
queue<site> q;
cin>>n;
for(int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
cin>>a[i][j];
for(int i = 1; i <= m; i++) {//将周围用墙围起来
a[i][0] = 1;
a[i][n+1] = 1;
}
for (int j = 1; j <= n; j++){//将周围用墙围起来
a[0][j] = 1;
a[m+1][j] = 1;
}
temp.x = 1;
temp.y = 1;
q.push(temp);
a[1][1] = 6;//搜索过的地方值变为6
while(!q.empty()){
temp = q.front();//取队首坐标
q.pop();
int x = temp.x, y = temp.y;
if(x == m && y == n) {//如果找到终点
flag = 0;
int k = 0;
p[k++] = temp;
while(temp.x != 1 || temp.y != 1){//将到终点的路线逆向保存
p[k++] = f[temp];
temp = f[temp];
}
for(int i = k-1; i >= 0; i--)//输出路线
cout<<p[i].x<<','<<p[i].y<<endl;
break;
}
for (int w = 0; w < 4; w++) {//遍历四个方向
temp.x = x + move[w][0];
temp.y = y + move[w][1];
if(a[temp.x][temp.y] == 0){
q.push(temp);
a[temp.x][temp.y] = 6;//搜索过的地方值变为6
f[temp].x = x;
f[temp].y = y;
}
}
}
if(flag)
cout<<"NO FOUND";
cout<<endl;
cin>>m;
}
return 0;
}

PTA7-1 迷宫寻路 (20分)的更多相关文章

  1. 抛弃EF,20分构建一个属于自己的ORM框架

    Poiuyt_cyc 博客园首页新随笔联系订阅管理随笔 - 11  文章 - 0  评论 - 111 抛弃EF,20分构建一个属于自己的ORM框架 相信EF大家都不陌生了,因为数据库表跟程序实体是一一 ...

  2. PTA 邻接表存储图的广度优先遍历(20 分)

    6-2 邻接表存储图的广度优先遍历(20 分) 试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(V ...

  3. #020PAT 没整明白的题L1-009 N个数求和 (20 分)

    后面的测试点过不去,两个错误一个超时. 目前未解决   L1-009 N个数求和 (20 分)   本题的要求很简单,就是求N个数字的和.麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和 ...

  4. L1-023 输出GPLT (20 分)

    L1-023 输出GPLT (20 分) 给定一个长度不超过10000的.仅由英文字母构成的字符串.请将字符重新调整顺序,按GPLTGPLT....这样的顺序输出,并忽略其它字符.当然,四种字符(不区 ...

  5. PAT 乙级 1074 宇宙无敌加法器 (20 分)

    1074 宇宙无敌加法器 (20 分) 地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的.而在 PAT 星人开挂的世界里,每个数字的每一位都是不同进制的,这种神奇的数字称为“PAT数”.每 ...

  6. PAT 乙级 1044 火星数字 (20 分)

    1044 火星数字 (20 分) 火星人是以 13 进制计数的: 地球人的 0 被火星人称为 tret. 地球人数字 1 到 12 的火星文分别为:jan, feb, mar, apr, may, j ...

  7. PAT 甲级 1035 Password (20 分)

    1035 Password (20 分) To prepare for PAT, the judge sometimes has to generate random passwords for th ...

  8. 获取数值型数组中大于60的元素个数,给数值型数组中不足60分的加20分。(数组,for循环,if条件判断语句)

    package com.Summer_0420.cn; /** * @author Summer * 获取数值型数组中大于60的元素个数 * 给数值型数组中不足60分的加20分 */ public c ...

  9. PAT 甲级 1041 Be Unique (20 分)

    1041 Be Unique (20 分) Being unique is so important to people on Mars that even their lottery is desi ...

随机推荐

  1. centos 7 部署 zookeeper

    Zookeeper集群搭建 由于公司缓存方案改进,准备采用codis集群作为主要的缓存解决方案(codis:国内豌豆荚开发的redis集群解决方案,已开源,github地址:https://githu ...

  2. YbtOJ#662-交通运输【线段树合并,树状数组】

    正题 题目链接:http://www.ybtoj.com.cn/contest/122/problem/2 题目大意 给出\(n\)个点的一棵有根树,对于每个\(x\)求,删除点\(x\)后修改某个点 ...

  3. 使用gitlab runner进行CI(三):使用sonarqube做c++的静态检查

    目录 1. gitlab-ci.yml的配置 1.1 几个基本概念 1.2 使用CI进行代码检查demo 2. Sonarqube安装和配置 2.1 Sonarqube安装 2.2 数据库配置 2.3 ...

  4. Netty 组件分析

    EventLoop 事件循环对象 EventLoop 本质是一个单线程执行器(同时维护了一个 Selector),里面有 run 方法处理 Channel 上源源不断的 io 事件. 它的继承关系比较 ...

  5. Java(3)基本数据类型及其类型转换

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201501.html 博客主页:https://www.cnblogs.com/testero ...

  6. Head First Python 代码和实例下载

    http://python.itcarlow.ie/resources.html

  7. javascript-jquery的基本方法

    1.去除字符串中两端的空格$.trim(str) var str1=" 123 " $.trim(str1);//123 2.遍历对象的数据并进行操作$.each(obj,func ...

  8. sql递归查询部门数据

    1 with cte as 2 ( 3 select a.DepartCode,a.DepartName,a.ParentDepartCode from tbDeparts a where Paren ...

  9. [no_code][Alpha]事后分析

    $( "#cnblogs_post_body" ).catalog() 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们要解决的 ...

  10. the Agiles Scrum Meeting 11

    会议时间:2020.4.20 20:00 1.每个人的工作 在这次例会上,我们对上周完成的工作进行了总结. 本周已完成的工作 个人结对项目增量开发组 tq: 创建广播功能 修复纯英文数字可能溢出bug ...