Uva 816 Abbott的复仇(三元组BFS + 路径还原)
题意:
有一个最多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 + 路径还原)的更多相关文章
- UVa 816 Abbott的复仇(BFS)
寒假的第一道题目,在放假回家颓废了两天后,今天终于开始刷题了.希望以后每天也能多刷几道题. 题意:这道BFS题还是有点复杂的,给一个最多9*9的迷宫,但是每个点都有不同的方向,每次进入该点的方向不同, ...
- uva 816 Abbott的复仇
题目链接:https://uva.onlinejudge.org/external/8/816.pdf 紫书:P165 题意: 有一个最多包含9*9个交叉点的迷宫.输入起点.离开起点时的朝向和终点,求 ...
- UVA - 816 Abbott's Revenge(bfs)
题意:迷宫从起点走到终点,进入某点的朝向不同,可以出去的方向也不同,输出最短路. 分析:因为朝向决定接下来在该点可以往哪里走,所以每个点需要有三个信息:x,y,d(坐标和进入该点的朝向),所以将起点的 ...
- UVA 816 -- Abbott's Revenge(BFS求最短路)
UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉 ...
- UVA 816 - Abbott's Revenge(BFS)
UVA 816 - Abbott's Revenge option=com_onlinejudge&Itemid=8&page=show_problem&category=59 ...
- 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, ...
- uva 816 - Abbott's Revenge(有点困难bfs迷宫称号)
是典型的bfs,但是,这个问题的目的在于读取条件的困难,而不是简单地推断,需要找到一种方法来读取条件.还需要想办法去推断每一点不能满足条件,继续往下走. #include<cstdio> ...
- Uva 816 Abbott's Revenge(BFS)
#include<cstdio> #include<cstring> #include<vector> #include<queue> using na ...
- UVA 816 Abbott’s Revenge
bfs求最短路,递归打印最短路的具体路径: 难点: 当前状态和转弯方式很复杂,要仔细处理: 递归打印:用一个数组存储路径中结点的前一个节点,递归查找 (bfs无法确定下一个结点,但对于没一个结点,它的 ...
随机推荐
- python网络爬虫之二requests模块
requests http请求库 requests是基于python内置的urllib3来编写的,它比urllib更加方便,特别是在添加headers, post请求,以及cookies的设置上,处理 ...
- _bzoj2243 [SDOI2011]染色【树链剖分】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 裸的树链剖分,最开始我保存一个线段树节点的color值时(若有多种颜色则为-1),不小 ...
- iOS- NSThread/NSOperation/GCD 三种多线程技术的对比及实现 -- 转
1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题 ...
- Kali linux 2016.2(Rolling)里的枚举服务
前言 枚举是一类程序,它允许用户从一个网络中收集某一类的所有相关服务.
- java之数据处理,小数点保留位数
1.返回字符串类型,保留后两位: public static String getRate(Object d) { return String.format("%.2f", d); ...
- Java开发笔记(九十三)深入理解字节缓存
前面介绍了文件通道的读写操作,其中用到字节缓存ByteBuffer,它是位于通道内部的存储空间,也是通道唯一可用的存储形式.ByteBuffer有两种构建方式,一种是调用静态方法wrap,根据输入的字 ...
- ie浏览器和火狐浏览器对对容器宽度定义的差异
首先我们说说firefox和IE对CSS的宽度显示有什么不同: 其实CSS ’width’ 指的是标准CSS中所指的width的宽度,在firefox中的宽度就是这个宽度.它只包含容器中内容的宽度.而 ...
- 学习笔记 第六章 使用CSS美化图片
第六章 使用CSS美化图片 6.1 在网页中插入图片 GIF图像 跨平台能力,无兼容性问题: 具有减少颜色显示数目而极度压缩文件的能力,不会降低图像的品质(无损压缩): 支持背景透明功能,便于图像 ...
- Fragment中获取Activity的Context (转)
Fragment中获取Activity的Context时只需要this.getActivity()即可. 而不是许多人说的this.getActivity().getApplicationCo ...
- python学习笔记-02
四.函数 1.定义函数 (1)定义规则 介绍列表方法的时候已经大概说过函数,学过数学的人都知道函数,给一个参数返回一个值.函数也可以自己定义.用如下的格式: >>>def 函数名(参 ...