UVA - 816 Abbott's Revenge(bfs)
题意:迷宫从起点走到终点,进入某点的朝向不同,可以出去的方向也不同,输出最短路。
分析:因为朝向决定接下来在该点可以往哪里走,所以每个点需要有三个信息:x,y,d(坐标和进入该点的朝向),所以将起点的下一个点当做初始状态
注意理解题意:进入交叉点的朝向与从哪个方向进交叉点正好相反
#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
typedef long long ll;
typedef unsigned long long llu;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {, , , -};
const int dc[] = {, , -, };
const int MOD = 1e9 + ;
const double pi = acos(-1.0);
const double eps = 1e-;
const int MAXN = + ;
const int MAXT = + ;
using namespace std;
char s[];
bool edge[][][][];
int dis[][][];
const char* a = "ESWN";//与数组dr,dc方向对应
const char* b = "LFR";
struct Node{
int x, y, d;//当前点的坐标,及进入该点的朝向
Node(){}
Node(int xx, int yy, int dd):x(xx), y(yy), d(dd){}
}num[][][];//记录该点的上一个点
int dir_id(char c){
return strchr(a, c) - a;
}
int turn_id(char c){
return strchr(b, c) - b;
}
bool judge(int x, int y){
return x >= && x <= && y >= && y <= ;
}
Node next(const Node&t, int turn){//turn与字符数组b下标对应
int dir = t.d;//向前走朝向不变
if(!turn){//向左走
dir = (dir + ) % ;//减1等价于加3
}
else if(turn == ){
dir = (dir + ) % ;
}
return Node(t.x + dr[dir], t.y + dc[dir], dir);
}
void print_ans(Node t, int tx, int ty, int dir){
stack<Node> st;
while(){
st.push(t);
if(dis[t.x][t.y][t.d] == ) break;
t = num[t.x][t.y][t.d];
}
st.push(Node(tx, ty, dir));
int cnt = ;
while(!st.empty()){
Node tmp = st.top();
st.pop();
++cnt;
if(cnt % == ) printf(" ");
printf(" (%d,%d)", tmp.x, tmp.y);
if(cnt % == ) printf("\n");
}
if(cnt % != ) printf("\n");
}
bool bfs(int sx, int sy, int dir, int ex, int ey){
memset(dis, -, sizeof dis);
queue<Node> q;
q.push(Node(sx, sy, dir));
dis[sx][sy][dir] = ;
int tx = sx - dr[dir];//迷宫起点
int ty = sy - dc[dir];
while(!q.empty()){
Node t = q.front();
q.pop();
if(t.x == ex && t.y == ey){
print_ans(t, tx, ty, dir);
return true;
}
for(int i = ; i < ; ++i){
Node v = next(t, i);
if(edge[t.x][t.y][t.d][i] && judge(v.x, v.y) && dis[v.x][v.y][v.d] < ){
dis[v.x][v.y][v.d] = dis[t.x][t.y][t.d] + ;
num[v.x][v.y][v.d] = t;
q.push(v);
}
}
}
return false;
}
int main(){
while(scanf("%s", s) == ){
if(strcmp(s, "END") == ) return ;
printf("%s\n", s);
memset(edge, , sizeof edge);
int sx, sy, ex, ey;
char dir;
scanf("%d%d %c%d%d", &sx, &sy, &dir, &ex, &ey);
int d = dir_id(dir);//进起点的下一个点的朝向
int nx = sx + dr[d];//起点的下一个位置
int ny = sy + dc[d];
int x;
while(scanf("%d", &x) == ){
if(x == ) break;
int y;
scanf("%d", &y);
while(scanf("%s", s) == ){
if(s[] == '*') break;
int tmp_dir = dir_id(s[]);
int len = strlen(s);
for(int i = ; i < len; ++i){
int tmp_turn = turn_id(s[i]);
edge[x][y][tmp_dir][tmp_turn] = ;
}
}
}
bool ok = bfs(nx, ny, d, ex, ey);//起点的下一个点因为已知,所以将其当为开始的点
if(!ok){
printf(" No Solution Possible\n");
}
}
return ;
}
UVA - 816 Abbott's Revenge(bfs)的更多相关文章
- UVa 816 Abbott的复仇(BFS)
寒假的第一道题目,在放假回家颓废了两天后,今天终于开始刷题了.希望以后每天也能多刷几道题. 题意:这道BFS题还是有点复杂的,给一个最多9*9的迷宫,但是每个点都有不同的方向,每次进入该点的方向不同, ...
- UVA 816 - Abbott's Revenge(BFS)
UVA 816 - Abbott's Revenge option=com_onlinejudge&Itemid=8&page=show_problem&category=59 ...
- UVA 816 -- Abbott's Revenge(BFS求最短路)
UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉 ...
- UVA 816 Abbott’s Revenge
bfs求最短路,递归打印最短路的具体路径: 难点: 当前状态和转弯方式很复杂,要仔细处理: 递归打印:用一个数组存储路径中结点的前一个节点,递归查找 (bfs无法确定下一个结点,但对于没一个结点,它的 ...
- Uva 816 Abbott的复仇(三元组BFS + 路径还原)
题意: 有一个最多9*9个点的迷宫, 给定起点坐标(r0,c0)和终点坐标(rf,cf), 求出最短路径并输出. 分析: 因为多了朝向这个元素, 所以我们bfs的队列元素就是一个三元组(r,c,dir ...
- Uva 816 Abbott's Revenge(BFS)
#include<cstdio> #include<cstring> #include<vector> #include<queue> using na ...
- uva 816 abbott's revenge ——yhx
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAncAAAN5CAYAAABqtx2mAAAgAElEQVR4nOy9sY4jydKezVuoayhH0r
- UVa 439骑士的移动(BFS)
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- Uva - 816 - Abbott's Revenge
这个迷宫问题还是挺好玩的,多加了一个转向的问题,有些路口不同的进入方式会有不同的转向限制,这个会比较麻烦一点,所以定义结点结构体的时候需要加一个朝向dir.总体来说是一道BFS求最短路的问题.最后打印 ...
随机推荐
- eclipse问题集合
[eclipse更换jdk版本]
- SpringMVC 接收表单数据、数据绑定、解决请求参数中文乱码
接收表单数据有3种方式. 1.使用简单类型接收表单数据(绑定简单数据类型) 表单: <form action="${pageContext.request.contextPath}/u ...
- Python简单程序爬取天气信息,定时发邮件给朋友【高薪必学】
前段时间看到了这个博客.https://blog.csdn.net/weixin_45081575/article/details/102886718.他用了request模块,这不巧了么,正好我刚用 ...
- 设计模式课程 设计模式精讲 8-3 单例设计模式-DoubleCheck双重检查实战及原理解析
1 课程讲解 1.1 为何要使用双重检查 1.2 双重检查的缺点 1.3 指令重排序讲解 1.4 指令重排序比喻(自己理解) 1.5 如何解决指令重排序问题 2 代码演练 2.1 代码演练1(双重检查 ...
- elasticsearch mapping简单介绍
这两天一直在看elasticsearch相关的内容,看到mapping这一块,就折腾了下. 一般情况下,我们不需要对elasticsearch的mapping进行设置,但如果希望对索引使用自定义的管理 ...
- 算法设计与分析 - AC 题目 - 第 5 弹(重复第 2 弹)
PTA-算法设计与分析-AC原题 - 最大子列和问题 (20分) 给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+, ..., Nj },其中 ≤i ...
- windows索引服务
windows索引服务是windows操作系统提供的桌面搜索引擎,通过预先创建索引来提高对硬盘上文件内容的搜索速度.以windows服务程序的方式运行. 一.工作方式 1.对指定路径下的文件创 ...
- ASC码速记
ASCII表规则记忆 我们仅仅要记住了一个字母或数字的 ASCII 码 (比如记住 A 为 65 , 0 的 ASCII 码为 48 ), 知道对应的大写和小写字母之间差 32. 0 -- 32 按键 ...
- 吴裕雄--天生自然HADOOP操作实验学习笔记:pvuv统计案例理论
实验目的 复习pv.uv的概念和原理 了解pv.uv的实际意义和获取方法 实验原理 前面我们已经基于mapreduce进行数据的etl处理,实验有很多不足之处,这次实验我们是基于url数据进行pv和u ...
- struts的错误回显