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

  本题思路:保存起点和终点的状态,保存每个顶点的状态,包括每个方向的可转向方向,然后直接BFS即可,记得保存每个儿子结点的爹,便于回溯输出路径。

  参考代码:

 #include <bits/stdc++.h>
using namespace std; struct Node{
int r, c, dir;// 表示结点的横纵坐标和方向
Node(int r = , int c = , int dir = ) :r(r), c(c), dir(dir) {};//对结构体元素进行初始化
};
const int maxn = ;
const char *dirs = "NESW";
const char *turns = "FLR";
const int dr[] = {-, , , };
const int dc[] = {, , , -};
int has_edge[maxn][maxn][][];//保存(r, c, dir)状态下的可移动方向
int d[maxn][maxn][];//存储初始状态到(r, c, dir)的最短路长度
Node p[maxn][maxn][];//同时用p[r][c][dir]保存了状态(r, c, dir)在BFS树中的父节点
int r0, c0, dir, r1, c1, r2, c2;
char name[]; int dir_id(char c) {
return strchr(dirs, c) - dirs;
} int turn_id(char c) {
return strchr(turns, c) - turns;
} 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);
} bool inside(int r, int c) {
return r >= && r <= && c >= && c <=;
} bool read_case () {
char s[], s2[];
scanf("%s", name);
if(!strcmp(name, "END")) return false;
scanf("%d %d %s %d %d", &r0, &c0, s2, &r2, &c2);
cout << name << endl;
dir = dir_id(s2[]);
r1 = r0 + dr[dir];
c1 = c0 + dc[dir];
memset(has_edge, , sizeof(has_edge));
while(true) {
int r, c;
scanf("%d", &r);
if(r == ) break;
scanf("%d", &c);
while(~scanf("%s", s) && s[] != '*') {
for(int i = ; i < strlen(s); i ++)
has_edge[r][c][dir_id(s[])][turn_id(s[i])] = ;
}
}
return true;
} void print_ans(Node u) {
//从目标节点逆序回溯到初始结点
vector <Node> nodes;
while(true) {
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));
//打印解,每行10个
int cnt = ;
for(int i = nodes.size() - ; i >= ; i --) {
if(cnt % == ) printf(" ");
printf(" (%d,%d)", nodes[i].r, nodes[i].c);
if(++ cnt % == ) printf("\n");
}
if(nodes.size() % != ) printf("\n");
} 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) {
print_ans(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_case()) {
solve();
}
return ;
}

UVA-816.Abbott's Tevenge (BFS + 打印路径)的更多相关文章

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

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

  2. Uva 816 Abbott's Revenge(BFS)

    #include<cstdio> #include<cstring> #include<vector> #include<queue> using na ...

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

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

  4. POJ 3414 Pots ( BFS , 打印路径 )

    题意: 给你两个空瓶子,只有三种操作 一.把一个瓶子灌满 二.把一个瓶子清空 三.把一个瓶子里面的水灌到另一个瓶子里面去(倒满之后要是还存在水那就依然在那个瓶子里面,或者被灌的瓶子有可能没满) 思路: ...

  5. UVa 103 - Stacking Boxes (LIS,打印路径)

    链接:UVa 103 题意:给n维图形,它们的边长是{d1,d2,d3...dn},  对于两个n维图形,求满足当中一个的全部边长 依照随意顺序都一一相应小于还有一个的边长,这种最长序列的个数,而且打 ...

  6. Uva 10131 Is Bigger Smarter? (LIS,打印路径)

    option=com_onlinejudge&Itemid=8&page=show_problem&problem=1072">链接:UVa 10131 题意: ...

  7. Codeforces 3A-Shortest path of the king(BFS打印路径)

    A. Shortest path of the king time limit per test 1 second memory limit per test 64 megabytes input s ...

  8. BFS+打印路径

    题目是给你起点sx,和终点gx:牛在起点可以进行下面两个操作: 步行:John花一分钟由任意点X移动到点X-1或点X+1. 瞬移:John花一分钟由任意点X移动到点2*X. 你要输出最短步数及打印路径 ...

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

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

随机推荐

  1. tensorflow实战系列(二)TFRecordReader

    前面写了TFRecordWriter的生成.这次写TFRecordReader. 代码附上: def read_and_decode(filename):    #根据文件名生成一个队列    fil ...

  2. JDK7和JDK8concurrentHashmap区别

    哈希表 1.介绍 哈希表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值. 哈希的思路很简单,如果所有的键都是整数,那么就可以使用一个 ...

  3. js人形时钟

    https://blog.csdn.net/rsylqc/article/details/44808063 分享自:http://chabudai.org/blog/?p=59 在这个网站看到一个很有 ...

  4. English-新概念学习

    English-英语字母发音全攻略.pdf English-新概念第一册笔记.rar English-新概念第二册笔记.rar English-新概念第三册笔记.rar English-英语训练用书. ...

  5. 设计模式入门——Head First

    设计模式是被前人发现.经过总结形成了一套某一类问题的一般性解决方案.使用模式最好的方式是:把模式装进脑子,然后在设计和已有的应用中,寻找何处可以使用它们.以往是代码复用,现在是经验复用. 从模拟鸭子游 ...

  6. Haskell语言学习笔记(79)lambda演算

    lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...

  7. Redis进阶实践之三如何在Windows系统上安装安装Redis(转载)

    Redis进阶实践之三如何在Windows系统上安装安装Redis 一.Redis的简介 Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括 ...

  8. 【369】列表/字典的分拆, unpacking

    参考: python--参数列表的分拆 参考: List Comprehensions 当你要传递的参数已经是一个列表,调用的函数却接受分开一个个的参数,这个时候可以考虑参数列表拆分: 可以使用* 操 ...

  9. Mysql 6.0安装过程(截图放不上去)

      由于免费,MySQL数据库在项目中用的越来越广泛,而且它的安全性能也特别高,不亚于oracle这样的大型数据库软件.可以简单的说,在一些中小型的项目中,使用MySQL ,PostgreSQL是最佳 ...

  10. thread == 票池

    public class ThreadDemo2 { public static void main(String[] args){ TicketPool tp = new TicketPool(); ...