原题链接: UVa-816

题目大意:

模有一个最多包含9*9个交叉点的迷宫。输入起点、离开起点时的朝向和终点,求一条最短路径。(具体题目参考原题和紫书)

解题思路:

本题是一道用BFS求最短路径的迷宫题。不过和普通的迷宫不太一样,该题加了一个朝向和转向的概念。可以想象成十字路口修路,限制道路前进方向(不太准确)。这道题看的时候完全没有思路,虽然写过用BFS求解迷宫的问题,但是想了半个多小时也没有思路(你好菜啊),然后就去看紫书上给的思路,之后大概明白了一点,然后就开始按着刘汝佳给的思路和代码写了写。其实还是有些地方不是特别明白,所以有错误的地方,希望大家见谅(你来咬我啊)。

整体思路就是在读入的时候构造一个四维的数组has_edge[r][c][d][t]来存储,在交叉点(r,c)能朝向d时向t方向转向。同时还要读取输入起点(r0,c0)、离开起点时的朝向(d)和终点(r2,c2),并将起点(r0,c0),朝d方向走到(r1,r1)。然后使用BFS的框架从寻找最短路径。

刘汝佳给的代码里有很多处理的很巧妙的地方比如朝向和转向的处理,还有就是walk函数。

遇到问题:

参考别人的代码没有自己写着有成就感,所以写到中间有点不太想写了,很懈怠,所以出了很多小问题(比如==写出=),导致后来花了很长时间去调试。

感悟:

 过一段时间,这个题应该再返工一次。

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<queue>using namespace std;struct Node
{int x, y, dir;Node() {}Node(int x, int y, int d = -1) :x(x), y(y), dir(d) {}
};const int MAXN = 9 + 5;
const char *dircs = "NESW";
const char *turns = "FLR";
const int dr[4] = { -1,0,1,0 };
const int dc[4] = { 0,1,0,-1 };
int d[MAXN][MAXN][4], has_edge[MAXN][MAXN][4][3];
Node p[MAXN][MAXN][4];
string name;int dir_id(char c) { return strchr(dircs, c) - dircs; } //返回c在dircs的下标
int turn_id(char c) { return strchr(turns, c) - turns; }
void inti(Node& begin, Node& end);
bool inside(int x, int y);
void print(Node u, Node begin);
void BFS(const Node begin, const Node end);
Node walk(const Node& u, int turn);int main()
{//freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout); while (cin >> name && name != "END"){Node begin, end;inti(begin, end);BFS(begin, end);}return 0;
}void BFS(const Node begin, const Node end)
{queue<Node> q;Node u = walk(begin, 0);p[u.x][u.y][u.dir] = begin;d[u.x][u.y][u.dir] = 0;q.push(u);while (!q.empty()){Node u = q.front(); q.pop();if (u.x == end.x && u.y == end.y){print(u, begin);return;}for (int i = 0; i < 3; i++){Node v = walk(u, i);if (has_edge[u.x][u.y][u.dir][i] && inside(v.x, v.y) && d[v.x][v.y][v.dir] < 0){d[v.x][v.y][v.dir] = d[u.x][u.y][u.dir] + 1;p[v.x][v.y][v.dir] = u;q.push(v);}}}cout << name << endl << "  No Solution Possible\n";
}void print(Node u, Node begin)
{vector<Node> v;while (1){v.push_back(u);if (d[u.x][u.y][u.dir] == 0)break;u = p[u.x][u.y][u.dir];}v.push_back(begin);cout << name;for (int i = v.size() - 1; i >= 0; i--){if ((v.size()- 1-i) % 10 == 0)cout << endl << " ";cout << " (" << v[i].x << "," << v[i].y << ")";}cout << endl;
}bool inside(int x, int y)
{if (x < 1 || y < 1 || x > 9 || y > 9)return false;return true;
}Node walk(const Node& u, int turn)
{int dir = u.dir;if (turn == 1) dir = (dir + 3) % 4;if (turn == 2) dir = (dir + 1) % 4;return Node(u.x + dr[dir], u.y + dc[dir], dir);
}void inti(Node &begin, Node &end)
{int x, y;string s;cin >> x >> y >> s;begin = Node(x, y, dir_id(s[0]));cin >> x >> y;end.x = x; end.y = y;memset(has_edge, 0, sizeof(has_edge));memset(d, -1, sizeof(d));while (cin >> x && x){cin >> y;while (cin >> s && s != "*"){int dir = dir_id(s[0]);for (int i = 1; i < s.length(); i++){int turn = turn_id(s[i]);has_edge[x][y][dir][turn] = 1;}}}
}

UVa816 例题 6-14 Abbott的复仇 (Abbott's Revenge,ACM/ICPC World Finals 2000)相关推荐

  1. UVA816 Abbott的复仇 Abbott's Revenge(final的BFS)(真•答案)

    题目 写这道题差点没把我气死,网上的好多题解看了半天结果是假的- 题目PDF [分析] 利用队列实现广度搜索BFS来遍历图寻找最短路径. 用一个三元组(r, c, dir)表示"位于(r, ...

  2. 《算法竞赛入门经典》 例题 4-4 信息编码 (Message Decoding,ACM,ICPC World Finals 1991,UVa 213)

    原题及翻译 Some message encoding schemes require that an encoded message be sent in two parts. 某些消息编码方案要求 ...

  3. 例题5-10 PGA巡回赛的奖金(PGA Tour Prize Money,ACM/ICPC World Finals 1990 UVa207)

    原题链接:https://vjudge.net/problem/UVA-207 分类:耐力 备注:排序和其他细节处理 前言:这是我第二次默写刘老师的代码了,真的崩溃,错一点点细节都不行,对着uDebu ...

  4. 例题6-2 铁轨(Rails, ACM/ICPC CERC 1997, UVa 514)

    栈应用 例题6-2 铁轨(Rails, ACM/ICPC CERC 1997, UVa 514) 错解 1.每次要把栈清空 2.不能用空的栈(栈顶)去比较 #include<iostream&g ...

  5. [uva816]AbbottsRevenge Abbott的复仇(经典迷宫BFS)

    这题思路就普通的BFS加上一个维度朝向,主要是要注意输入,输出,以及细节的处理 #include<cstdio> #include<cstring> #include<q ...

  6. 信息学奥赛一本通例题2.14~2.16

    例2.14 已知某班有男同学x位,女同学y位,x位男生平均分是87分,y位女生的平均分是85,问全体同学平均分是多少分? [分析] 男女生的人数需要用户输入,然后根据题意(x87+y85)/(x+y) ...

  7. (翻译)复仇模式(Revenge)

    问题概述   人们喜欢以其人之道还治其人之身[1]. 用途 用于鼓励使用复仇方式增强游戏可玩性:在游戏或挑战中击败朋友: 如果复仇行为以不和收场,且结局并不是皆大欢喜,不要使用本模式[2]. 说明   ...

  8. 例题3-6 环状序列(Circular Sequence, ACM/ICPC Seoul 2004, UVa1584)

    长度为n的环状串有n种表示法,分别为从某 个位置开始顺时针得到.例如,图3-4的环状串 有10种表示: CGAGTCAGCT,GAGTCAGCTC,AGTCAGCTCG等.在这些表示法中,字典序最小的 ...

  9. 例题3-5 生成元(Digit Generator, ACM/ICPC Seoul 2005, UVa1583)

    如果x加上x的各个数字之和得到y,就说x是y的生成元.给出n(1≤n≤100000),求最小 生成元.无解输出0.例如,n=216,121,2005时的解分别为198,0,1979. 先附上自己的想法 ...

最新文章

  1. Microsoft Enterprise Library 5.0 系列(八) Unity Dependency Injection and Interception
  2. 医院管理系统的新机遇
  3. NWERC 2018 A. Access Points 二维转一维 + 单调栈
  4. JavaFX拖放事件
  5. 数字电影打包内容(Packaging)
  6. (四)深入浅出TCPIP之TCP三次握手和四次挥手(下)的抓包分析
  7. 1_RabbitMQ初入门入门Hello消费者+生产者
  8. SQL Server-聚焦LEFT JOIN...IS NULL AND NOT EXISTS性能分析(十七)
  9. C# 实现 Hyper-V 虚拟机 管理
  10. 《麦肯锡方法》读书笔记15
  11. 奔图3305_奔图 Pantum P3305DN 驱动
  12. Google推出即时通讯软件Hello
  13. html有哪些段落及排版标记,04.HTML排版标记
  14. MOSFET的雪崩特性
  15. 基于matlab的车牌定位算法设计与实现,原创】基于matlab的汽车牌照识别系统设计与实现...
  16. git版本回退命令_刘先生
  17. MYSQL——触发器
  18. 【TS TSP】基于matlab禁忌搜索求解旅行商问题【含Matlab源码 447期】
  19. 计算机在维氏硬度的应用,华银显微维氏硬度计HVS-1000A使用方法
  20. WORD文档打开文件时老提示发送错误报告,或者打印不全

热门文章

  1. 微信小程序生成海报可保存海报和分享海报
  2. 文件加载出现 _pickle.UnpicklingError: could not find MARK
  3. python绘制太阳系模型_太阳系模型Python列表操作困难
  4. MaTeX:在Mathematica的图片中插入LaTeX代码的工具
  5. php的laravel框架下载,PHP 之 Laravel 框架安装及相关开源软件
  6. 阿里规范-为什么不允许魔法值(即未经定义的常量)出现在代码中?
  7. OPPO的低代码实践:InnerEye低代码大屏
  8. horspool算法C语言代码,sfa3
  9. 如何选购合适的IPKVM切换器
  10. Python和numpy下载安装方法