题意:迷宫从起点走到终点,进入某点的朝向不同,可以出去的方向也不同,输出最短路。

分析:因为朝向决定接下来在该点可以往哪里走,所以每个点需要有三个信息: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)的更多相关文章

  1. UVa 816 Abbott的复仇(BFS)

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

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

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

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

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

  4. UVA 816 Abbott’s Revenge

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

  5. Uva 816 Abbott的复仇(三元组BFS + 路径还原)

    题意: 有一个最多9*9个点的迷宫, 给定起点坐标(r0,c0)和终点坐标(rf,cf), 求出最短路径并输出. 分析: 因为多了朝向这个元素, 所以我们bfs的队列元素就是一个三元组(r,c,dir ...

  6. Uva 816 Abbott's Revenge(BFS)

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

  7. uva 816 abbott's revenge ——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAncAAAN5CAYAAABqtx2mAAAgAElEQVR4nOy9sY4jydKezVuoayhH0r

  8. UVa 439骑士的移动(BFS)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  9. Uva - 816 - Abbott's Revenge

    这个迷宫问题还是挺好玩的,多加了一个转向的问题,有些路口不同的进入方式会有不同的转向限制,这个会比较麻烦一点,所以定义结点结构体的时候需要加一个朝向dir.总体来说是一道BFS求最短路的问题.最后打印 ...

随机推荐

  1. Linux centos7iptables filter表案例、iptables nat表应用

    一.iptables filter表案例 vim /usr/local/sbin/iptables.sh 加入如下内容 #! /bin/bash ipt="/usr/sbin/iptable ...

  2. 分布式事务中间件 TCC-Transaction 源码分析 —— 项目实战

    https://blog.csdn.net/lldouble/article/details/79455172

  3. FFmpeg——AVFrame中 的 data

    AVFrame中 的 data 的定义如下: typedef struct AVFrame { #define AV_NUM_DATA_POINTERS 8 /** * pointer to the ...

  4. error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 解决方法

    在VS2012中生成时出错:error C4430: missing type specifier - int assumed. Note: C++ does not support default- ...

  5. Centos7 设置自定义安装nginx的systemctl启动方式

    一.systemctl方式启动设置过程 1.首先创建服务配置文件(名字和路径就是这个) vim /usr/lib/systemd/system/nginx.service 2.添加配置内容 [Unit ...

  6. MySql的数据导入到Sql Server数据库中

    步骤一:安装MySql驱动 驱动下载链接:https://dev.mysql.com/downloads/connector/odbc/ 下载完成后安装, 一路Next即可 步骤二:创建DSN DSN ...

  7. C++ 定位错误行

    ] = {}; SYSTEMTIME st; GetLocalTime(&st); sprintf_s(buf, , "%02d-%02d-%02d %02d:%02d:%02d | ...

  8. android图片保存到SQLlite如何实现?

    //写入数据库               ImageView pic = (ImageView) findViewById(R.id.picture);                        ...

  9. 与(&)、非(~)、或(|)、异或(^)

    位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面 ...

  10. 剑指offer 把数组排成最小的数 atoi和itoa,pow

    pow(x,y)在#include<math.h>文件中,计算x的y次方. C++引入头文件:#include <stdlib.h> 或者 #include <cstdl ...