UVa 816 Abbott的复仇(BFS)
寒假的第一道题目,在放假回家颓废了两天后,今天终于开始刷题了。希望以后每天也能多刷几道题。
题意:这道BFS题还是有点复杂的,给一个最多9*9的迷宫,但是每个点都有不同的方向,每次进入该点的方向不同,允许出去的方向也不同。所以在记录迷宫的时候比较麻烦,可以用一个四元组has_edge[10][10][4][4]来记录,前两个元素代表坐标点,第三个元素代表进入该点时的方向,第四个元素代表离开该点时的方向。在BFS遍历时还是和以前的题目差不多的,记录好路径,最后回溯输出就行。
我还犯了个小错误,因为我用的是getline来输入每个迷宫的名字,所以在每次while循环最后应该加一句getchar()来吃掉回车。不然第二次循环时字符串就是回车了,这样就出错了。
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
using namespace std; struct node
{
int rr, cc, dir;
node(int a, int b, int c) { rr = a; cc = b; dir = c; }
node(){}
}; string str; int r0,c0,r1,c1,r2,c2;
char dir; const char* dirs = "NESW";
const char* turns = "FLR"; int dir_id(char c) { return strchr(dirs, c) - dirs; } //查找字符串中首次出现c的位置
int turn_id(char c) { return strchr(turns, c) - turns; } const int dr[] = { -, , , };
const int dc[] = { , , , - }; int has_edge[][][][]; int d[][][];
node v[][][]; node walk(const node &u, int turn)
{
int dir = u.dir;
if (turn == ) dir = (dir + ) % ;
if (turn == ) dir = (dir + ) % ;
return node(u.rr + dr[dir], u.cc + dc[dir], dir);
} bool inside(int x, int y)
{
if (x< && x> && y< && y>)
return true;
return false;
} void printfff(node u)
{
vector<node> nodes;
for (;;)
{
nodes.push_back(u);
if (d[u.rr][u.cc][u.dir] == ) break;
u = v[u.rr][u.cc][u.dir];
}
nodes.push_back(node(r0, c0, dir_id(dir))); int cnt = ;
for (int i = nodes.size() - ; i >= ; i--)
{
if (cnt % == ) printf(" ");
printf(" (%d,%d)", nodes[i].rr, nodes[i].cc);
if (++cnt % == ) cout << endl;
}
if (nodes.size() % != ) cout << endl;
} void BFS()
{
queue<node> q;
memset(d, -, sizeof(d));
node p(r1, c1, dir_id(dir));
d[p.rr][p.cc][p.dir] = ;
q.push(p);
while (!q.empty())
{
node p = q.front();
q.pop();
if (p.rr == r2 && p.cc == c2)
{
printfff(p);
return;
}
for (int k = ; k < ; k++)
{
node r = walk(p, k);
if (has_edge[p.rr][p.cc][p.dir][k] && inside(r.rr, r.cc) && d[r.rr][r.cc][r.dir]<)
{
d[r.rr][r.cc][r.dir] = d[p.rr][p.cc][p.dir] + ;
v[r.rr][r.cc][r.dir] = p;
q.push(r);
}
}
}
printf(" No Solution Possible\n");
} int main()
{
int x, y;
while (getline(cin,str) && str!= "END")
{
cout << str << endl;
memset(has_edge, , sizeof(has_edge));
cin >> r0 >> c0 >> dir >> r2 >> c2;
r1 = r0 + dr[dir_id(dir)]; //计算出初始位置点
c1 = c0 + dc[dir_id(dir)];
while (cin >> x && x != )
{
cin >> y;
char ch[];
while (cin >> ch && ch[] != '*')
{
int DIR = dir_id(ch[]);
int l = strlen(ch);
for (int i = ; i < l; i++)
{
int TURN = turn_id(ch[i]);
has_edge[x][y][DIR][TURN] = ;
}
}
}
BFS();
getchar();
}
return ;
}
UVa 816 Abbott的复仇(BFS)的更多相关文章
- UVA 816 -- Abbott's Revenge(BFS求最短路)
UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉 ...
- Uva 816 Abbott的复仇(三元组BFS + 路径还原)
题意: 有一个最多9*9个点的迷宫, 给定起点坐标(r0,c0)和终点坐标(rf,cf), 求出最短路径并输出. 分析: 因为多了朝向这个元素, 所以我们bfs的队列元素就是一个三元组(r,c,dir ...
- uva 816 Abbott的复仇
题目链接:https://uva.onlinejudge.org/external/8/816.pdf 紫书:P165 题意: 有一个最多包含9*9个交叉点的迷宫.输入起点.离开起点时的朝向和终点,求 ...
- Uva 816 Abbott's Revenge(BFS)
#include<cstdio> #include<cstring> #include<vector> #include<queue> using na ...
- UVA 816 - Abbott's Revenge(BFS)
UVA 816 - Abbott's Revenge option=com_onlinejudge&Itemid=8&page=show_problem&category=59 ...
- uva 816 - Abbott's Revenge(有点困难bfs迷宫称号)
是典型的bfs,但是,这个问题的目的在于读取条件的困难,而不是简单地推断,需要找到一种方法来读取条件.还需要想办法去推断每一点不能满足条件,继续往下走. #include<cstdio> ...
- UVA - 816 Abbott's Revenge(bfs)
题意:迷宫从起点走到终点,进入某点的朝向不同,可以出去的方向也不同,输出最短路. 分析:因为朝向决定接下来在该点可以往哪里走,所以每个点需要有三个信息:x,y,d(坐标和进入该点的朝向),所以将起点的 ...
- uva 816 abbott's revenge ——yhx
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAncAAAN5CAYAAABqtx2mAAAgAElEQVR4nOy9sY4jydKezVuoayhH0r
- UVA 816 Abbott’s Revenge
bfs求最短路,递归打印最短路的具体路径: 难点: 当前状态和转弯方式很复杂,要仔细处理: 递归打印:用一个数组存储路径中结点的前一个节点,递归查找 (bfs无法确定下一个结点,但对于没一个结点,它的 ...
随机推荐
- 【Machine Learning in Action --2】K-近邻算法构造手写识别系统
为了简单起见,这里构造的系统只能识别数字0到9,需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:宽高是32像素的黑白图像.尽管采用文本格式存储图像不能有效地利用内存空间,但是为了方便理 ...
- CTRL key
ctrl key其实是用于扩展键盘,单独一个ctrl键没有什么作用,也没有ascii码,当与其他键相结合时,相当于创造出一个新键.例如:用getchar()侦测输入的字符,当按下ctrl+a时,只输出 ...
- MyEclipse 2015 运行tomcat 内存溢出的解决方法
内存溢出错误: 2016-3-16 11:19:55 org.apache.catalina.core.StandardWrapperValve invoke严重: Servlet.service() ...
- HUST - 1599 Multiple
input 长度不大于3*10e5的数字串 output 不含前导0的能整除64的字串的个数(0算一个,064不算) 一般数组中找能整除一个数的字串都是用取余来做的 用一个a[64]来存下从1-i位累 ...
- dirname(_file_) DIRECTORY_SEPARATOR
<?php echo __FILE__ ; // 取得当前文件的绝对地址,结果:D:\www\test.php echo dirname(__FILE__); // 取得当前文件所在的绝对目录, ...
- js对象大总结2016/4/19
本地对象(非静态对象) 常用的对象Object,Funcion,Array,Boolen,String,Boolen,Number,Date,RegEXP,Error;new一下就能用的 内置对象:( ...
- POJ 1236 Network of Schools (tarjan算法+缩点)
思路:使用tarjan求强连通分量并进行缩点,判断所有入度为0的点,这个点就是必须要给予文件的点,分别计算出度,入度为零的点的个数,取二者的最大值就是把这个图变成强连通需要加的边数. 一个取值需要讨论 ...
- android:contentDescription的作用是什么
在写Android的XML布局文件时,在ImageView或ImageButton中经常会碰到一个提示: Missing contentDescription attribute on image. ...
- JavaBean,List,Map转成json格式
public class User { private String username; private String password; public String getUsername() { ...
- linux自动化构建工具-scons指南
1.scons是linux下的自动构建工具 scons是用Python编写的,使用scons之前需确认是否已经安装了Python.(在系统的命令行中运行python -V或python --versi ...