UVa (一道比较复杂的广搜) 816 Abbott’s Revenge
题意:
给出一个迷宫,在迷宫的节点处,面向某个方向只能向给定的方向转弯。给出起点和终点输出迷宫的最短路径,这里指的是刚刚离开起点的时刻,所以即使起点和终点重合路径也非空。
分析:
用三个变量来表示状态,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的更多相关文章
- UVA 816 -- Abbott's Revenge(BFS求最短路)
UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉 ...
- 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 ...
- UVa 10047 自行车 状态记录广搜
每个格子(x,y,drection,color) #include<iostream> #include<cstdio> #include<cstring> #in ...
- uva 816 abbott's revenge ——yhx
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAncAAAN5CAYAAABqtx2mAAAgAElEQVR4nOy9sY4jydKezVuoayhH0r
- Uva - 816 - Abbott's Revenge
这个迷宫问题还是挺好玩的,多加了一个转向的问题,有些路口不同的进入方式会有不同的转向限制,这个会比较麻烦一点,所以定义结点结构体的时候需要加一个朝向dir.总体来说是一道BFS求最短路的问题.最后打印 ...
- UVA 816 Abbott’s Revenge
bfs求最短路,递归打印最短路的具体路径: 难点: 当前状态和转弯方式很复杂,要仔细处理: 递归打印:用一个数组存储路径中结点的前一个节点,递归查找 (bfs无法确定下一个结点,但对于没一个结点,它的 ...
- Uva 816 Abbott's Revenge(BFS)
#include<cstdio> #include<cstring> #include<vector> #include<queue> using na ...
- UVA 816 Abbott's Revenge 紫书
紫书的这道题, 作者说是很重要. 但看着题解好长, 加上那段时间有别的事, 磨了几天没有动手. 最后,这道题我打了五遍以上 ,有两次被BUG卡了,找了很久才找到. 思路紫书上有,就缺少输入和边界判断两 ...
- UVA - 816 Abbott's Revenge(bfs)
题意:迷宫从起点走到终点,进入某点的朝向不同,可以出去的方向也不同,输出最短路. 分析:因为朝向决定接下来在该点可以往哪里走,所以每个点需要有三个信息:x,y,d(坐标和进入该点的朝向),所以将起点的 ...
随机推荐
- PHP命名空间(Namespace)
http://www.jb51.net/article/36389.htm 字符串形式的动态调用方式 //魔法常量__NAMESPACE__的值是当前空间名称 //可以组合成字符串并调用 $comme ...
- Android ListVIew 详解(一)
在android开发中ListView是比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示.抽空把对ListView的使用做了整理,并写了个小例子,如下图. 列表的显示需要三 ...
- iOS多线程的初步研究(六)-- NSOperation
iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管理线程的运行,从而更加简洁地实 ...
- sql连接字符串的方法
----乌龟代码---合并列值 --********************************************************************************** ...
- js中几个正则表达式相关函数使用时g标志的作用
首先,javascript中涉及到正则表达式的函数总共有6个,可分为两种: 1.第一种是作为字符串对象的方法,即以 String.fun(); 形式调用,这里包括 split.search.match ...
- LR实现http协议性能测试脚本
1. GET方式的HTTP请求性能测试脚本 Action() { web_set_max_html_param_len("); web_reg_save_param("retCo ...
- libevent简单介绍
http://blog.csdn.net/mafuli007/article/details/7476014 1 简介 主页:http://www.monkey.org/~provos/li ...
- ps里面的批处理教程
先打开窗口-动作 1.新建动作文件 打开一张图片,进行图片编辑,编辑完就是把图片保存在一个文件里面.停止动作. 再去打开ps文件-自动- 批处理 只要把 包含所有子文件夹(I)勾起来就行了 设置就能完 ...
- WPF之RichTextBox丢失光标仍然选中文本
描述:开发中完成了一个类似于Word的悬浮工具栏功能,选中文本之后可以自动弹出一个工具栏.可以修改字体.字体大小等功能,问题来了,我发现当去进行操作的时候原本选中的RichTextBox的内容的颜色会 ...
- Intellij Idea 15 生成serialVersionUID的方法
默认情况下Intellij IDEA是关闭了继承了Serializable接口的类生成serialVersionUID的警告.如果需要ide提示生成serialVersionUID,那么需要做以下设置 ...