UVA-816.Abbott's Tevenge (BFS + 打印路径)
本题大意:给定一个迷宫,让你判断是否能从给定的起点到达给定的终点,这里起点需要输入起始方向,迷宫的每个顶点也都有行走限制,每个顶点都有特殊的转向约束...具体看题目便知...
本题思路:保存起点和终点的状态,保存每个顶点的状态,包括每个方向的可转向方向,然后直接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 + 打印路径)的更多相关文章
- UVA 816 -- Abbott's Revenge(BFS求最短路)
UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉 ...
- Uva 816 Abbott's Revenge(BFS)
#include<cstdio> #include<cstring> #include<vector> #include<queue> using na ...
- UVA 816 - Abbott's Revenge(BFS)
UVA 816 - Abbott's Revenge option=com_onlinejudge&Itemid=8&page=show_problem&category=59 ...
- POJ 3414 Pots ( BFS , 打印路径 )
题意: 给你两个空瓶子,只有三种操作 一.把一个瓶子灌满 二.把一个瓶子清空 三.把一个瓶子里面的水灌到另一个瓶子里面去(倒满之后要是还存在水那就依然在那个瓶子里面,或者被灌的瓶子有可能没满) 思路: ...
- UVa 103 - Stacking Boxes (LIS,打印路径)
链接:UVa 103 题意:给n维图形,它们的边长是{d1,d2,d3...dn}, 对于两个n维图形,求满足当中一个的全部边长 依照随意顺序都一一相应小于还有一个的边长,这种最长序列的个数,而且打 ...
- Uva 10131 Is Bigger Smarter? (LIS,打印路径)
option=com_onlinejudge&Itemid=8&page=show_problem&problem=1072">链接:UVa 10131 题意: ...
- 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 ...
- BFS+打印路径
题目是给你起点sx,和终点gx:牛在起点可以进行下面两个操作: 步行:John花一分钟由任意点X移动到点X-1或点X+1. 瞬移:John花一分钟由任意点X移动到点2*X. 你要输出最短步数及打印路径 ...
- Uva 816 Abbott的复仇(三元组BFS + 路径还原)
题意: 有一个最多9*9个点的迷宫, 给定起点坐标(r0,c0)和终点坐标(rf,cf), 求出最短路径并输出. 分析: 因为多了朝向这个元素, 所以我们bfs的队列元素就是一个三元组(r,c,dir ...
随机推荐
- PHP提取HTML代码中img标签下src属性
需求:提取整片文章中img的src属性,并保存到一个数组当中 preg_match_all("/(href|src)=([\"|']?)([^\"'>]+.(jpg ...
- Oracle的基本数据类型(常用)
转自:https://www.2cto.com/database/201810/783959.html 1.字符型 Char 固定长度字符串 占2000个字节 Varchar2 可变长度字符串 占40 ...
- 机器学习进阶-目标跟踪-KCF目标跟踪方法 1.cv2.multiTracker_create(构造选框集合) 2. cv2.TrackerKCF_create(获得KCF追踪器) 3. cv2.resize(变化图像大小) 4.cv2.selectROI(在图像上框出选框)
1. tracker = cv2.multiTracker_create() 获得追踪的初始化结果 2.cv2.TrackerKCF_create() 获得KCF追踪器 3.cv2.resize(fr ...
- jinjia
https://www.cnblogs.com/dachenzi/p/8242713.html
- Python文件和目录模块介绍:glob、shutil、ConfigParser
glob模块 查找符合特定规则的文件路径名,路径名可以使用绝对路径也可以使用相对路径.查找文件会使用到三个通配符,星号*,问号?和中括号[],其中"*"表示匹配0~n个字符, &q ...
- thread == 票池
public class ThreadDemo2 { public static void main(String[] args){ TicketPool tp = new TicketPool(); ...
- .Net中使用ODP.net访问Oracle数据库
ODP.Net是Oracle提供的数据库访问类库,其功能和效率上都有所保证,它还有一个非常方便特性:在客户端上,可以不用安装Oracle客户端,直接拷贝即可使用. .net framework4中会将 ...
- 使用 COM 类库创建链接桌面快捷方式
用到的 COM 类库: Windows Script Host Object Model --> Interop.IWshRuntimeLibrary.dll 示例代码: private sta ...
- EF 1
安装框架: 在NuGet中安装ef框架,命令:Install-package EntityFramework 数据迁移: 在程序包管理器控制台,执行语句. 初始化: 1.Enable-Migratio ...
- 学JS的心路历程 -数组常见处理方法
昨天我们有提到说for-of和forEach可以用来处理数组,但其实还有很多方法可以更快速及精简代码的达到你要的效果. 话不多说,我们赶紧来看吧! Array.prototype.map() 会回传一 ...