题意:

给出一个迷宫,在迷宫的节点处,面向某个方向只能向给定的方向转弯。给出起点和终点输出迷宫的最短路径,这里指的是刚刚离开起点的时刻,所以即使起点和终点重合路径也非空。

分析:

用三个变量来表示状态,r,c,dir,分别代表所处的位置和朝向。在输入数据的同时,也要初始化has_edge[r][c][dir][turn],代表处于(r, c, dir)这个状态时能否向turn转弯。

结构体数组p用来保存路径。

因为路径可能比较长,所以如果采用地轨输出的话,可能会栈溢出。代码中采用了动态数组来输出。

一直WA的原因:读入函数Input返回值是bool,而只在代码中写了return false; 却没有在最后加上 return true;

 //#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std; struct Node
{
int r, c;
int dir;
Node(int rr=, int cc=, int ddir=):r(rr), c(cc), dir(ddir) {}
}; const char* dirs = "NESW";
const char* turns = "FLR";
int dir_id(char c) { return strchr(dirs, c) - dirs; }
int turn_id(char c) { return strchr(turns, c) - turns; }
const int dr[] = {-, , , };
const int dc[] = {, , , -};
int d[][][];
Node p[][][];
int r0, c0, r1, dir, c1, r2, c2;
char name[], c[], s[];
bool has_edge[][][][]; bool inside(int r, int c)
{ return (r>= && r<= && c>= && c<=); } bool Input()
{
if(scanf("%s%d%d%s%d%d", name, &r0, &c0, &c, &r2, &c2)!=) return false;
printf("%s\n", name);
dir = dir_id(c[]);
r1 = r0 + dr[dir];
c1 = c0 + dc[dir]; memset(has_edge, false, sizeof(has_edge));
int a, b;
while(scanf("%d", &a))
{
if(a == ) break;
scanf("%d", &b);
while(scanf("%s", s))
{
if(s[] == '*') break;
int tempd = dir_id(s[]);
for(int i = ; i < strlen(s); ++i)
has_edge[a][b][tempd][turn_id(s[i])] = true;
}
}
return true;
} 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);
} void print_ans(Node u)
{
vector<Node> nodes;
for(;;)
{
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)); 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[r1][c1][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);
}
}
}
puts(" No Solution Possible");
} int main(void)
{
#ifdef LOCAL
freopen("816in.txt", "r", stdin);
#endif while(Input())
{
solve();
} return ;
}

代码君

UVa (一道比较复杂的广搜) 816 Abbott’s Revenge的更多相关文章

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

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

  2. UVa 1600 Patrol Robot(三维广搜)

    A robot has to patrol around a rectangular area which is in a form of m x n grid (m rows and ncolumn ...

  3. UVa 10047 自行车 状态记录广搜

    每个格子(x,y,drection,color) #include<iostream> #include<cstdio> #include<cstring> #in ...

  4. uva 816 abbott's revenge ——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAncAAAN5CAYAAABqtx2mAAAgAElEQVR4nOy9sY4jydKezVuoayhH0r

  5. Uva - 816 - Abbott's Revenge

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

  6. UVA 816 Abbott’s Revenge

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

  7. Uva 816 Abbott's Revenge(BFS)

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

  8. UVA 816 Abbott's Revenge 紫书

    紫书的这道题, 作者说是很重要. 但看着题解好长, 加上那段时间有别的事, 磨了几天没有动手. 最后,这道题我打了五遍以上 ,有两次被BUG卡了,找了很久才找到. 思路紫书上有,就缺少输入和边界判断两 ...

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

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

随机推荐

  1. C++时间标准库时间time和系统时间的使用

    #include <iostream> #include <time.h> #include <stdio.h> #include <windows.h> ...

  2. 网格导入设置 Import settings for Meshes

    原地址:http://game.ceeger.com/Components/FBXImporter-Model.html The Import Settings for a model file wi ...

  3. php7 安装 及和php5的共存

    http://blog.csdn.net/liuxinmingcode/article/details/50319145 LNMP FastCGI 是一个可伸缩地.高速地在HTTP server和动态 ...

  4. setTimeout延时0毫秒的作用和问题

    一 作用 http://www.cnblogs.com/xieex/archive/2008/07/11/1241151.html 经常看到setTimeout延时0ms的javascript代码,感 ...

  5. sql 数据库换行

    制表符 CHAR(9)  换行符 CHAR(10)  回车 CHAR(13) 

  6. lintcode:移动零

    题目 给一个数组 nums 写一个函数将 0 移动到数组的最后面,非零元素保持原数组的顺序 注意事项 1.必须在原数组上操作2.最小化操作数   样例 给出 nums = [0, 1, 0, 3, 1 ...

  7. shape和selector的结合使用

    shape和selector是Android UI设计中经常用到的,比如我们要自定义一个圆角Button,点击Button有些效果的变化,就要用到shape和selector.可以这样说,shape和 ...

  8. java多线程知识点总结

    1.线程调度知识:线程类Thread的了解,几个thread的方法.thread.sleep(),thread.join().(调用join方法的那个线程会立刻执行). object.wait()方法 ...

  9. Linux服务器 scp 不需要密码配置与密钥转换(id_rsa->ppk)

    案例:▲服务器A对服务器B.C进行ssh连接,免输入密码    或▲服务器A向服务器B.C复制文件(源文件在服务器A上),免输入密码 主机A:192.168.0.221主机B:192.168.0.22 ...

  10. STM32的GPIO口的输出开漏输出和推挽输出

    本文来自cairang45的博客,讲述了STM32的GPIO口的输出开漏输出和推挽输出, 作者博客:http://blog.ednchina.com/cairang45 本文来自: 高校自动化网(Ww ...