题意:

有一个最多9*9个点的迷宫, 给定起点坐标(r0,c0)和终点坐标(rf,cf), 求出最短路径并输出。

分析:

因为多了朝向这个元素, 所以我们bfs的队列元素就是一个三元组(r,c,dir),然后做好输入处理的细节, 这题的关键在于bfs中的路径还原。

其实bfs的过程就是一棵树,如下图

除了起点外, 每个点都有且只有一个父亲节点, 那么我们只需要开一个pre数组来记录每个点的父亲, 找到终点后从终点往上不断找父亲节点, 直到找到父亲节点, 那么就完成了路径还原的

步骤。

 #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) {}
}; int have_edge[][][][];
int d[][][];
Node pre[][][];
int r0,c0,r1,c1,rf,cf,init_dir;
const char* dirs = "NESW"; //
const char* turns = "FLR";//0不动 1左 顺时针 2右 逆时针 int id_dir(char s){ return strchr(dirs,s) - dirs;}
int id_turn(char s){return strchr(turns,s) - turns;} const int dr[] = {-, , , }; //dirs为上右下左
const int dc[] = {, , , -}; bool input(){
char s1[], s2[];
int o;
if((o = scanf("%s%d%d%s%d%d",s1,&r0,&c0,s2,&rf,&cf) )!= ) { return false;}
printf("%s\n", s1);
init_dir = id_dir(s2[]);
r1 = r0 + dr[init_dir];
c1 = c0 + dc[init_dir];
// printf("%d %d %d\n", init_dir,r1,c1);
memset(have_edge,,sizeof(have_edge));
for(;;){
int r,c;
scanf("%d", &r);
if(r == ) break;
scanf("%d", &c);
while(scanf("%s", &s2) && s2[] != '*'){
int len = strlen(s2);
for(int i = ; i < len; i++){
have_edge[r][c][id_dir(s2[])][id_turn(s2[i])] = ;
}
}
}
return true;
}
Node walk(const Node& u, int turn){
int dir = u.dir;
if(turn == ) dir = (u.dir+)%;
else if(turn == ) dir = (u.dir+) %;
return Node(u.r + dr[dir], u.c + dc[dir] , dir);
} bool inside(int r, int c) {
return r >= && r <= && c >= && c <= ;
}
void print_ans(Node u){
vector<Node> ans;
for(;;){
ans.push_back(u);
if(d[u.r][u.c][u.dir] == )
break;
u = pre[u.r][u.c][u.dir];
}
ans.push_back(Node(r0,c0,init_dir)); int cnt = ;
for(int i = ans.size() -; i >= ; i--){
if(cnt % == ) printf(" ");
printf(" (%d,%d)", ans[i].r, ans[i].c);
if(++cnt % == ) printf("\n");
}
if(ans.size() % != ) printf("\n");
}
void solve(){
queue<Node> q;
memset(d,-,sizeof(d));
d[r1][c1][init_dir] = ;
Node u(r1,c1,init_dir);
q.push(u);
while(!q.empty()){
Node u = q.front(); q.pop();
// printf("$ u %d %d %d\n",u.r, u.c,u.dir);
if(u.r == rf && u.c == cf){
print_ans(u);
return;
}
for(int i = ; i < ; i++){
Node v;
if(have_edge[u.r][u.c][u.dir][i])
v = walk(u,i);
// printf("& v %d %d %d\n",v.r, v.c, v.dir);
if(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] + ;
pre[v.r][v.c][v.dir] = u;
q.push(v);
}
}
}
printf(" No Solution Possible\n");
}
int main(){
while(input()){
solve();
}
return ;
}

Uva 816 Abbott的复仇(三元组BFS + 路径还原)的更多相关文章

  1. UVa 816 Abbott的复仇(BFS)

    寒假的第一道题目,在放假回家颓废了两天后,今天终于开始刷题了.希望以后每天也能多刷几道题. 题意:这道BFS题还是有点复杂的,给一个最多9*9的迷宫,但是每个点都有不同的方向,每次进入该点的方向不同, ...

  2. uva 816 Abbott的复仇

    题目链接:https://uva.onlinejudge.org/external/8/816.pdf 紫书:P165 题意: 有一个最多包含9*9个交叉点的迷宫.输入起点.离开起点时的朝向和终点,求 ...

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

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

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

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

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

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

  6. POJ-3894 迷宫问题 (BFS+路径还原)

    定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, ...

  7. uva 816 - Abbott&#39;s Revenge(有点困难bfs迷宫称号)

    是典型的bfs,但是,这个问题的目的在于读取条件的困难,而不是简单地推断,需要找到一种方法来读取条件.还需要想办法去推断每一点不能满足条件,继续往下走. #include<cstdio> ...

  8. Uva 816 Abbott's Revenge(BFS)

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

  9. UVA 816 Abbott’s Revenge

    bfs求最短路,递归打印最短路的具体路径: 难点: 当前状态和转弯方式很复杂,要仔细处理: 递归打印:用一个数组存储路径中结点的前一个节点,递归查找 (bfs无法确定下一个结点,但对于没一个结点,它的 ...

随机推荐

  1. 从Oracle9i RMAN全库备份迁移到 Oracle10g

    1. 创建以下目录: mkdir -pv $ORACLE_BASE/admin/$ORACLE_SID/{{a,b,c,dp,u}dump,pfile} mkdir -pv $ORACLE_BASE/ ...

  2. 《windows核心编程系列》十九谈谈使用远程线程来注入DLL。

    windows内的各个进程有各自的地址空间.它们相互独立互不干扰保证了系统的安全性.但是windows也为调试器或是其他工具设计了一些函数,这些函数可以让一个进程对另一个进程进行操作.虽然他们是为调试 ...

  3. 【小程序】基于.NET CORE2.1 的 微信开放平台 第三方平台开发 教程一 准备工作

    微信第三方平台概述 公众平台第三方平台是为了让公众号或小程序运营者,在面向垂直行业需求时,可以一键授权给第三方平台(并且可以同时授权给多家第三方),通过第三方平台来完成业务,开放给所有通过开发者资质认 ...

  4. 208 Implement Trie (Prefix Tree) 字典树(前缀树)

    实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个方法.注意:你可以假设所有的输入都是小写字母 a-z.详见:https://leetcode.co ...

  5. .vimrc文件配置及含意

    1.  vimrc文件常见语句释义 设定 tab 的位置          :set tabstop=4 输入 tab 时自动将其转化为空格          :set expandtab       ...

  6. Laravel环境搭建

    在有了初步认知后,当然就要开始在自己的电脑上搭建Laravel的开发环境了. 系统环境需求 PHP 5.3.7或者更高版本,如果没有系统没有安装PHP环境的,请到下面地址下载:http://cn2.p ...

  7. HTML5 File API的应用

    HTML5 File API简介 HTML5File API协议族 Directories and System   文件系统和目录读取 FileWriter   写入文件 FileReader   ...

  8. 对openjdk的javac编译器扩展了一个语法糖

    我的扩展功能描述如下: 在java的现有语法中加入var来声明变量,并且可以根据初始化数据来自动类型推导. 举两个例子: 例一: 如下JAVA代码(注意这里的var是新语法): import java ...

  9. vscode增加sftp扩展

    下载 sftp-sync 扩展插件 填写配置 快捷键 ctrl+shift+P 打开指令窗口,输入sftp:config,回车,就会在当前工作工程的.vscode文件夹下生成一个sftp.json文件 ...

  10. rabbitmq在storm中使用

    storm中只能进行任务计算,不能保存中间结果,最后结果. 这就有一个需求,保存计算结果,最好还是分布式的,因为storm也是分布式,大数据计算. 流行的分布式计算中使用队列保存数据居多. kafka ...