题意:

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

分析:

用三个变量来表示状态,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. Maven在项目中的应用

    http://192.168.0.253:8081/nexus/#view-repositories;thirdparty~uploadPanel 使用局域网搭建的环境,输入用户名和密码登录,上传ja ...

  2. jquery json遍历和动态绑定事件

    <div id='tmpselectorList' style='border: 1px solid grey;max-height: 150px;position:absolute;text- ...

  3. mapred和mapreduce

    总体上看,Hadoop MapReduce分为两部分:一部分是org.apache.hadoop.mapred.*,这里面主要包含旧的API接口以及MapReduce各个服务(JobTracker以及 ...

  4. HDU 1028 Ignatius and the Princess III (递归,dp)

    以下引用部分全都来自:http://blog.csdn.net/ice_crazy/article/details/7478802  Ice—Crazy的专栏 分析: HDU 1028 摘: 本题的意 ...

  5. UVA 562 Dividing coins (01背包)

    题意:给你n个硬币,和n个硬币的面值.要求尽可能地平均分配成A,B两份,使得A,B之间的差最小,输出其绝对值.思路:将n个硬币的总价值累加得到sum,   A,B其中必有一人获得的钱小于等于sum/2 ...

  6. C# 中Newtonsoft.Json的安装和使用

    官网参考:http://json.codeplex.com/ 在程序包管理控制台,键入NuGet命令  install-package Newtonsoft.Json  安装Newtonsoft.Js ...

  7. .htaccess的基本作用及相关语法介绍

    .htaccess是一个纯文本文件,它里面存放着Apache服务器配置相关的指令. .htaccess主要的作用有:URL重写.自定义错误页面.MIME类型配置以及访问权限控制等.主要体现在伪静态的应 ...

  8. hdu 3537 Daizhenyang's Coin (翻硬币游戏)

    #include<stdio.h> #include<algorithm> #include<string.h> using namespace std; ]; i ...

  9. Android核心分析之十四Android GWES之输入系统

          Android输入系统 依照惯例,在研究Android输入系统之前给出输入系统的本质描述:从哲学的观点来看,输入系统就是解决从哪里来又将到哪里去问题.输入的本质上的工作就是收集用户输入信息 ...

  10. Maven的安装

    我对maven的了解,仅仅局限在百度百科. 由于近期公司需求,我找到了个maven教程:http://wentao365.iteye.com/blog/903396 安装maven其实很简单,就是在A ...