题意:

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

分析:

用三个变量来表示状态,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. IE6 png 透明--四种解决方法

    FF和IE7已经直接支持透明的png图了,下面这个主要是解决IE6下透明PNG图片有灰底的 方法一:定义一个样式,给某个div应用这个样式后,div的透明png背景图片自动透明了.(注意两处图片的路径 ...

  2. sqoop导入hdfs上的数据到oracle

    /opt/sqoop-/bin/sqoop export --table mytablename --connect jdbc:oracle:thin:@**.**.**.**:***:dbasena ...

  3. **apache环境下 禁止显示 index of/ 目录下(如何禁止访问网站根目录)

    比如: http://123.57.49.XX6// 当这样访问的时候,可能会列出网站的根目录 如何禁止列出网站目录,方法如下: 让别人知道你的网站目录结构直接查看你目录下的所有文件是很危险的一个事情 ...

  4. AssemblyInfo.cs文件参数具体讲解

    在asp.net中有一个配置文件AssemblyInfo.cs主要用来设定生成的有关程序集的常规信息dll文件的一些参数,下面是默认的AssemblyInfo.cs文件的内容具体介绍 //是否符合公共 ...

  5. 快速构建自己的CentOS发行版

    一.制作LTOS具体过程 光盘结构介绍 * isolinux 目录存放光盘启动时的安装界面信息 * images 目录包括了必要的启动映像文件 * CentOS 目录存放安装软件包及信息 * .dis ...

  6. Mysql笔记——DDL

    数据库模式定义语言DDL(Data Definition Language),是用于描述数据库中要存储的现实世界实体的语言.一个数据库模式包含该数据库中所有实体的描述定义.   =========== ...

  7. Android百度地图开发02之添加覆盖物 + 地理编码和反地理编码

    下面来看一下地图上覆盖物的添加,以及地理编码和反地理编码. 添加覆盖物 在地图上添加覆盖物,一般需要以下几个步骤: 1. 定义坐标点,有可能是一个,有可能是多个(比如:多边形覆盖物). 2. 构造Ov ...

  8. 使用 Dalvik 调试监控服务 (DDMS) 工具

    Android 附带一个叫Dalvik 调试监控服务 (DDMS) 的调试工具,它提供端口转发服务.在设备上的屏幕捕获,设备上的线程和堆栈信息, logcat,进程, 和无线状态信息,接收呼叫和SMS ...

  9. Objective-C:自定义Block函数

    Block函数是一种类似于函数指针的函数,程序员只需要把需要操作的代码封装到定义的block中即可,以后需要使用时,直接调用,非常方便.... 举例如下: 第一种形式:自定义一个无返回值而且无参数的b ...

  10. Data Flow ->> Merge

    Merge组件的作用和Union All很相似,就是把两个输入源的结果集合并成一个.但是不同之处在于: 1)Merge输入的结果集需要先经过排序(这点表示怀疑) 2)Merge对于输入的两个结果集的数 ...