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

  本题思路:保存起点和终点的状态,保存每个顶点的状态,包括每个方向的可转向方向,然后直接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. SpringBoot 整合 devtools 实现热部署

    来源:https://www.cnblogs.com/rcddup/p/7533125.html 一.添加 devtools 依赖 <!-- Spring boot 热部署 : 此热部署会遇到 ...

  2. Redis 内存溢出过期策略

    1: 设置内存最大值, 如果该主机只作为 redis 服务器, 无其它比较占用资源的服务, 建议设置为内存的 3/4 大小, 单位 B 2: 设置内存溢出解决策略, 推荐 1-5 任选一种, 不推荐 ...

  3. dubbo超时优先级设置

    调用超时配置的优先级 可以在多个配置项设置超时,由上至下覆盖(即上面的优先),示例如下: # 其它的参数(retries.loadbalance.actives等)的覆盖策略也一样. 提供者端特定方法 ...

  4. 文件系统(File System)

    什么是文件系统,引用百科解释: 操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统. 文件系统是操作系统核心的组成部分,没有它我们无法完成对文件的增.删.改.查等基本操作 概念 ...

  5. delphi ios info.plist

    delphi ios info.plist delphi修改info.plist.TemplateiOS.xml文件,然后自动生成project1.info.plist http://docwiki. ...

  6. Linux:写一个简单的服务器

    开始了新篇章:Linux网络编程. 基础知识: 套接字概念 Socket本身有"插座"的意思,在Linux环境下,用于表示进程间网络通信的特殊文件类型.本质为内核借助缓冲区形成的伪 ...

  7. Spring事务管理——回滚(rollback-for)控制

    探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...

  8. 【365】拉格朗日乘子法与KKT条件说明

    参考:知乎回答 - 通过山头形象描述 参考:马同学 - 如何理解拉格朗日乘子法? 参考: 马同学 - 如何理解拉格朗日乘子法和KKT条件? 参考:拉格朗日乘数 - Wikipedia 自己总结的规律 ...

  9. 记Dagger2使用过程中的一个BUG--compileGoogleDebugJavaWithJavac

    项目编译可以通过,不过没有生成Dagger2的类,导致无法运行项目.. 错误提示 Error:(14, 41) 错误: 找不到符号 符号: 类 DaggerAppComponent 位置: 程序包 c ...

  10. [重点]delphi 实现 根据给定的标题去《中国青年报》网上电子报数据中查找匹配的内容,并从该内容中取出引题、正题、副题、作者和正文。

    项目要求:根据给定的标题去<中国青年报>网上电子报数据中查找匹配的内容,并从该内容中取出引题.正题.作者和正文. unit Unit1; interface uses Winapi.Win ...