紫书的这道题, 作者说是很重要。

但看着题解好长, 加上那段时间有别的事, 磨了几天没有动手。

最后,这道题我打了五遍以上 ,有两次被BUG卡了,找了很久才找到。

思路紫书上有,就缺少输入和边界判断两个部分。不是因为紫书,应该也不会找到这个WF题吧,所以其余思路就不说了。 一些注释在代码中有。

代码:

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std; const int MAXN = ;
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[] = {, , , -}; struct Node
{
int r;
int c;
int dir;
Node(int rr=, int cc=, int d=):r(rr), c(cc), dir(d) {}
}; int has_edge[MAXN][MAXN][][];
int d[MAXN][MAXN][];//判断是否遍历过
Node p[MAXN][MAXN][];
int r0, c0, r1, c1, r2, c2, dir; 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);
} bool inside(int r, int c)//判断是否出界
{
return r>= && r<= && c>= && c<=;
} bool read_case()
{
char s1[], s2[];//储存名字, 储存方向
if(scanf("%s%d%d%s%d%d", s1, &r0, &c0, s2, &r2, &c2)!=) return false;//输入不正确
printf("%s\n", s1);
memset(has_edge, , sizeof(has_edge)); dir = dir_id(s2[]);
r1 = r0+dr[dir];
c1 = c0+dc[dir]; for(; ;)
{
int r, c;
scanf("%d", &r);
if(r==) break;
scanf("%d", &c);
while(scanf("%s", s2)== && s2[]!='*')
{
int len=strlen(s2);
for(int i=; i<len; i++)
has_edge[r][c][dir_id(s2[])][turn_id(s2[i])]=;//将可走的地方赋1
}
}
return true;
} 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--)//倒着输出
{
// cout<<"#i"<<endl;
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[u.r][u.c][u.dir]=;
q.push(u);
while(!q.empty())
{
Node now = q.front(); q.pop();
if(now.r==r2 && now.c==c2)
{
print_ans(now);
return;
} for(int i=; i<; i++)
{
Node v = walk(now, i);
if(has_edge[now.r][now.c][now.dir][i] && d[v.r][v.c][v.dir]< && inside(v.r, v.c))
{
d[v.r][v.c][v.dir] = d[now.r][now.c][now.dir]+;
p[v.r][v.c][v.dir] = now;
q.push(v);
}
}
}
printf(" No Solution Possible\n");
} int main()
{
while(read_case())
solve(); return ;
}

毕竟完成了一题WF题,虽然开始的思路不是自己想的,但还是感觉有一丝丝成就感,哈哈。

UVA 816 Abbott's Revenge 紫书的更多相关文章

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

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

  2. UVA 816 Abbott’s Revenge

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

  3. uva 816 abbott's revenge ——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAncAAAN5CAYAAABqtx2mAAAgAElEQVR4nOy9sY4jydKezVuoayhH0r

  4. Uva - 816 - Abbott's Revenge

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

  5. Uva 816 Abbott's Revenge(BFS)

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

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

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

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

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

  8. uva 816 Abbott的复仇

    题目链接:https://uva.onlinejudge.org/external/8/816.pdf 紫书:P165 题意: 有一个最多包含9*9个交叉点的迷宫.输入起点.离开起点时的朝向和终点,求 ...

  9. UVa 11582 Colossal Fibonacci Numbers! 紫书

    思路是按紫书上说的来. 参考了:https://blog.csdn.net/qwsin/article/details/51834161  的代码: #include <cstdio> # ...

随机推荐

  1. 解决django配合nginx部署后admin样式丢失

    解决django配合nginx部署后admin样式丢失 1.  在项目的settings.py文件里添加以下内容: STATIC_URL = '/static/' STATICFILES_DIRS = ...

  2. 【转】彻底理解android中的内部存储与外部存储

    我们先来考虑这样一个问题: 打开手机设置,选择应用管理,选择任意一个App,然后你会看到两个按钮,一个是清除缓存,另一个是清除数据,那么当我们点击清除缓存的时候清除的是哪里的数据?当我们点击清除数据的 ...

  3. 详解Tensorflow数据读取有三种方式(next_batch)

    转自:https://blog.csdn.net/lujiandong1/article/details/53376802 Tensorflow数据读取有三种方式: Preloaded data: 预 ...

  4. centos 6.8安装java环境

    1.rpm -qa |grep java   查看当前是否有java已经安装了,部分centos系统已经安装了的openjava环境,但是很多项目不熟要求的是要必须是sun的java环境 2.yum ...

  5. LeetCode872. Leaf-Similar Trees

    自己的代码: # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = ...

  6. JavaScript里的创建对象(一)

    一.序 面向对象有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.ECMA-262把对象定义为“无序属性的集合,其属性可以包含基本值.对象或者函数”. 使用Obje ...

  7. RS485接口为什么要接地

    RS485接口为什么要接地 RS485接口有三根线,分别是A.B和GND线.因为RS485是差分传输的,所以很多工程师以为GND地线不重要,经常不接,甚至有些工程为了节约成本用两芯线或者用视频线来传输 ...

  8. C++中数组名和指针的区别联系

    原文:http://www.cnblogs.com/ddx-deng/archive/2012/12/16/3755862.html 第一个结论: #include "iostream.h& ...

  9. [收藏转]由于CredSSP加密Oracle修正 导致远程桌面报错处理

    原文:https://blog.csdn.net/lanwilliam/article/details/80346792 由于win103月份的一个更新,导致mstsc突然无法连接服务器了,报错如标题 ...

  10. 洛谷 1440 求m区间内的最小值

    洛谷  1440 求m区间内的最小值 题目描述 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. ...