题目描述:

输入输出:

输入样例:

SAMPLE
3 1 N 3 3
1 1 WL NR *
1 2 WLF NR ER *
1 3 NL ER *
2 1 SL WR NF *
2 2 SL WF ELF *
2 3 SFR EL *
0
NOSOLUTION
3 1 N 3 2
1 1 WL NR *
1 2 NL ER *
2 1 SL WR NFR *
2 2 SR EL *
0
END
输出样例:
SAMPLE
(3,1) (2,1) (1,1) (1,2) (2,2) (2,3) (1,3) (1,2) (1,1) (2,1)
(2,2) (1,2) (1,3) (2,3) (3,3)
NOSOLUTION
No Solution Possible
思路:
将普通图(只含有两个方向的平面图)改为三元组表示的图,再在“平面图”的基础上调用BFS算法,求单元最短路径。输入输出很繁(对我这个菜鸡来说)。
还有就是行走函数根据转向不同将char类型的方向映射到两个一维的int上去的方式很巧妙(巧妙的加3加1取余4,就打乱原来的NESW逆时针顺序),
再通过dr,dc数组实现方向的变化和移动。注意初始位置(r1,c1)不是原始位置(r0,c0)。
开始将d数组初始化为-1,到d[r1][c1][dir]就为0(加了1)。所以在用vector反着打印路径时最后加一个(r0,c0)(未存)
代码:(有详细的但也难懂的注释)
 #include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#define max_n 10
using namespace std;
struct Node
{
int r;
int c;
int dir;
Node(int r1=,int c1=,int d1=) :r(r1),c(c1),dir(d1) {}
//构造Node,带有默认参数,不然会在Node p[][][]那里报错,认为这个语句是在构造Node
};
int d[max_n][max_n][];//表示初始状态到(r,c,dir)的最短路长度
Node p[max_n][max_n][];//保存了状态(r,c,dir)在BFS数中的父结点
int has_edge[max_n][max_n][][];//当前状态是(r,c,dir),是否可以沿着转弯方向turn行走 //行走
const char* dirs = "NESW"; //顺时针旋转的顺序
const char* turns = "FLR";
int dir_id(char c) {return strchr(dirs,c)-dirs;} //将char类型的dir转化为dirs中相应的所在位置
int turn_id(char c) {return strchr(turns,c)-turns;}//将char类型的turn在turns中找到对应的元素位置
const int dr[] = {-,,,};//用上面找到的元素位置来确定当前行行走方向
const int dc[] = {,,,-};//用上面找到的元素位置来确定当前列行走方向
char maze[];//迷宫名称
int r0,c0,dir;//原始位置和方向
int r1,c1;//初始位置和方向
int r2,c2;//目标位置
//巧妙的行走函数和对应关系
//dirs 0N 1E 2S 3W
//顺时针
//dir' 3 0 1 2
//逆时针
//dir' 1 2 3 0
//dr -1 0 1 0
//dc 0 1 0 -1
Node walk(const Node& u,int turn)
{
int dir = u.dir;
if(turn==) dir = (dir+)%;
if(turn==) dir = (dir+)%;
return Node(u.r+dr[dir],u.c+dc[dir],dir);
}
//判断越界函数
int inside(int r,int c)
{
return <r&&r<=&&<c&&c<=;
}
//输出函数
//要求:
//第一行输出迷宫名
//后几行输出路径,且除最后一行外,其他每行都是空两格+10个(r,c)形式空格分隔的坐标
void printa(Node u)
{
vector<Node> nodes;//可用递归方式打印,但可能溢栈,可改用循环,用vector存储
for(;;)
{
nodes.push_back(u);
if(d[u.r][u.c][u.dir]==) break;
u = p[u.r][u.c][u.dir];
}
nodes.push_back(Node(r0,c0,dir)); int cnt = ;
for(int i = nodes.size()-;i>=;i--)
{
if(cnt%==) //值得品味的细节1
{
printf(" ");
}
printf(" (%d,%d)",nodes[i].r,nodes[i].c);
if(++cnt%==)//值得品味的细节2
{
printf("\n");
}
}
if(nodes.size()%!=)
{
printf("\n");
}
}
//输入函数
//先读入迷宫名,若为END返回0,
//然后一行读入起点r,c,dir,终点r,c
//然后处理交叉处的方向改变,将这些信息用数组has_edge[r][c][dir][turn]记录下来,为以后BFS提供基础
//读到*结束小循环,读到0结束大循环
int read()
{
cin >> maze;
if(maze[]=='E'&&maze[]=='N'&&maze[]=='D'&&strlen(maze)==) return ;
cout << maze << endl;
memset(maze,,sizeof(maze[])); char dirs;
cin >> r0 >> c0 >> dirs >> r2 >> c2;
dir = dir_id(dirs);
r1 = r0+dr[dir];
c1 = c0+dc[dir];
memset(has_edge,,sizeof(has_edge)); for(;;)
{
int r,c;
cin >> r;
if(r==)
{
break;
}
cin >> c;
char chr[];
while(cin >> chr)
{
if(chr[]=='*')
{
break;
}
for(int i = ;i<strlen(chr);i++)
{
has_edge[r][c][dir_id(chr[])][turn_id(chr[i])] = ;
}
//cout << r << " " << c << " " << chr << endl;
memset(chr,,sizeof(chr[]));
}
}
return true;
}
//BFS主过程
void solve()
{
queue<Node>q;
memset(d,-,sizeof(d));
Node u(r1,c1,dir);
d[u.r][u.c][u.dir] = ;
q.push(u);
while(!q.empty())
{
Node u = q.front();q.pop();
if(u.r==r2&&u.c==c2)
{
printa(u);
return;
}
for(int i = ;i<;i++)
{
Node v = walk(u,i);
if(has_edge[u.r][u.c][u.dir][i]&&inside(v.r,v.c)&&d[v.r][v.c][v.dir]<)
{
d[v.r][v.c][v.dir] = d[u.r][u.c][u.dir] +;
p[v.r][v.c][v.dir] = u;
q.push(v);
} }
}
printf(" No Solution Possible\n");
}
int main()
{
while(read())
solve();
return ;
}

UVA816 Abbott's Revenge (三元组BFS)的更多相关文章

  1. UVa816 Abbott's Revenge

    Abbott's Revenge Time limit: 3.000 seconds Abbott’s Revenge  Abbott’s Revenge The 1999 World FinalsC ...

  2. UVA - 816 Abbott's Revenge(bfs)

    题意:迷宫从起点走到终点,进入某点的朝向不同,可以出去的方向也不同,输出最短路. 分析:因为朝向决定接下来在该点可以往哪里走,所以每个点需要有三个信息:x,y,d(坐标和进入该点的朝向),所以将起点的 ...

  3. UVA 816 -- Abbott's Revenge(BFS求最短路)

     UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉 ...

  4. UVA 816 - Abbott&#39;s Revenge(BFS)

    UVA 816 - Abbott's Revenge option=com_onlinejudge&Itemid=8&page=show_problem&category=59 ...

  5. L - Abbott's Revenge(比较复杂的bfs)

    Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UV ...

  6. Abbott's Revenge UVA - 816 (输出bfs路径)

    题目链接:https://vjudge.net/problem/UVA-816 题目大意: 有一个最多包含9*9 个交叉点的迷宫.输入起点,离开起点时的朝向和终点,求一条最短路(多解时任意输出 一个即 ...

  7. Uva 816 Abbott的复仇(三元组BFS + 路径还原)

    题意: 有一个最多9*9个点的迷宫, 给定起点坐标(r0,c0)和终点坐标(rf,cf), 求出最短路径并输出. 分析: 因为多了朝向这个元素, 所以我们bfs的队列元素就是一个三元组(r,c,dir ...

  8. UVA-816.Abbott's Tevenge (BFS + 打印路径)

    本题大意:给定一个迷宫,让你判断是否能从给定的起点到达给定的终点,这里起点需要输入起始方向,迷宫的每个顶点也都有行走限制,每个顶点都有特殊的转向约束...具体看题目便知... 本题思路:保存起点和终点 ...

  9. 【例题 6-14 UVA-816】Abbott's Revenge

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 预处理出某个方向的左边.前边.右边是哪个方向就好了. 然后就是普通的bfs了. hash存到某个点,走到这里的方向的最小距离. df ...

随机推荐

  1. [LeetCode] 602. Friend Requests II: Who Has Most Friend? 朋友请求 II: 谁有最多的朋友?

    In social network like Facebook or Twitter, people send friend requests and accept others' requests ...

  2. 【Python学习之三】流程控制语句

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 python3.6 一.条件分支if <条件判断1>: & ...

  3. MySQL之备份

    MySQL备份和备份 备份/还原 冷备:需要停止当前正在运行mysqld,然后直接拷贝或打包数据文件. 半热备:mysqldump+binlog --适合数据量比较小的应用 在线热备:AB复制 --实 ...

  4. 八、spring生命周期之BeanPostProcessor

    BeanPostProcessor我们一般称为Bean的后置处理器,它与我们前面介绍的InitialingBean.init-method等一样,都是在bean的初始化时被调用,具体的用法我们在举例中 ...

  5. 【转】Fuel-openstack的搭建(二)

    原文链接:https://blog.csdn.net/qq_35180983/article/details/82181525 部署Openstack 3.1 登陆 登陆http://10.20.0. ...

  6. CF-Technocup3 D Optimal Subsequences

    D Optimal Subsequences http://codeforces.com/contest/1227/problem/D2 显然,每次求的k一定是这个序列从大到小排序后前k大的元素. 考 ...

  7. ENSP静态链路聚合实验配置要点及实例

    链路聚合分为:静态链路聚合.动态链路聚合链路聚合的负载分担模式:对于二层数据流,系统会根据MAC地址(源mac地址和目的mac地址来计算),而对于三层数据流则会根据ip地址来进行负载分担计算. 静态链 ...

  8. LeetCode 566. 重塑矩阵(Reshape the Matrix)

    566. 重塑矩阵 566. Reshape the Matrix 题目描述 LeetCode LeetCode LeetCode566. Reshape the Matrix简单 Java 实现 c ...

  9. Linux学习-文件基础权限

    文件基本权限 drwxr-xr-x 第一个字符表示文件类型 d:表示是一个目录.-:表示这是一个普通的文件.l: 表示这是一个符号链接文件,实际上它指向另一个文件.b.c:分别表示区块设备和其他的外围 ...

  10. 微信小程序的登入与授权

    官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 小程序登录 小程序可以通 ...