UVA 816 bfs
算法入门经典上面的题。题目链接 uva816
大致题意
有一个最多包含9*9个交叉点的迷宫。输入起点、离开起点时的朝向和终点,求一条最短路(多解时任意输出一个即可)。详细题意请看原题
思路
其实就是bfs,但是难点在于转向,将四个方向和3种转弯方式编号为0~3和0~2。
下面是转弯函数的实现
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[]={-1, 0, 1, 0};
const int dc[]={ 0, 1, 0, -1};
node walk(const node &u,int turn)
{
int dir=u.dir;
if(turn==1) dir=(dir+3)%4;
if(turn==2) dir=(dir+1)%4;
return node(u.r+dr[dir],u.c+dc[dir],dir);
}
输入的时候读取交点的信息要注意处理。
利用has_edge[r][c][dir][turn]标记在坐标(r,c)处朝向dir转向turn能否成功。
AC代码
#include<iostream>//不需要判断边界、移动方向已经确定
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<sstream>
using namespace std;
int r0,c0,r1,c1,r2,c2;//r0、c0表示出发坐标 r2、c2是终点坐标
char dir0;//出发方向
const int maxn=11;
int has_edge[maxn][maxn][4][3],d[maxn][maxn][4];
struct node
{
int r,c,dir;//r行 c列 dir方向
node(int tr,int tc,int tdir)
{
r=tr;c=tc;dir=tdir;
}
node()
{
}
};
node p[maxn][maxn][4];
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[]={-1, 0, 1, 0};
const int dc[]={ 0, 1, 0, -1};
node walk(const node &u,int turn)
{
int dir=u.dir;
if(turn==1) dir=(dir+3)%4;
if(turn==2) dir=(dir+1)%4;
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]==0) break;
u=p[u.r][u.c][u.dir];
}
//打印解
int cnt=0;
for(int i=nodes.size()-1;i>=0;i--)
{
if(cnt%10==0) printf(" ");
printf(" (%d,%d)",nodes[i].r,nodes[i].c);
if(++cnt%10==0) printf("\n");
}
if(nodes.size()%10!=0) printf("\n");
}
void bfs()
{
int t=dir_id(dir0);
d[r0][c0][t]=0;
node temp(r0,c0,t);
d[r1][c1][t]=1;
node v(r1,c1,t);
p[r1][c1][t]= temp;
queue<node>q;
q.push(v);
while(!q.empty())
{
node u=q.front();
q.pop();
if(u.r==r2&&u.c==c2)
{
print_ans(u);
return;
}
for(int i=0;i<3;i++)
{
if(has_edge[u.r][u.c][u.dir][i])
{
v=walk(u,i);
if(d[v.r][v.c][v.dir]<0)
{
d[v.r][v.c][v.dir]=d[u.r][u.c][u.dir]+1;
p[v.r][v.c][v.dir]=u;
q.push(v);
}
}
}
}
printf(" No Solution Possible\n");
}
int main(void)
{
string name,pos;
int r,c;
string str;
stringstream ss;
while(cin>>name&&name!="END")
{
cin>>r0>>c0>>dir0>>r2>>c2;
//计算进入迷宫的坐标
if(dir0=='N') {r1=r0-1;c1=c0;}
else if(dir0=='E') {r1=r0;c1=c0+1;}
else if(dir0=='W') {r1=r0;c1=c0-1;}
else {r1=r0+1;c1=c0;}
memset(d,-1,sizeof(d));
memset(has_edge,0,sizeof(has_edge));
memset(p,0,sizeof(p));
getchar();
while(getline(cin,pos)&&pos!="0")
{
ss<<pos;
ss>>r>>c;
while(ss>>str)
{
if(str[0]!='*')
{
int dir=dir_id(str[0]);
for(int i=1;i<str.size();i++)
{
int turn=turn_id(str[i]);
has_edge[r][c][dir][turn]=1;
}
}
}
ss.clear();
}
cout<<name<<"\n";
bfs();
}
return 0;
}
如有不当之处欢迎指出!
UVA 816 bfs的更多相关文章
- UVa 816 (BFS求最短路)
/*816 - Abbott's Revenge ---代码完全参考刘汝佳算法入门经典 ---strchr() 用来查找某字符在字符串中首次出现的位置,其原型为:char * strchr (cons ...
- uva 816 BFS求最短路的经典问题……
一开始情况没有考虑周全,直接WA掉了, 然后用fgets()出现了WA,给改成scanf就AC了 题目不是很难,用心就好…… #include <iostream> #include &l ...
- 【紫书】【重要】Abbott's Revenge UVA - 816 bfs 复杂模拟 带方向参数的迷宫
题意:一个迷宫,每个交叉路口有一路标,限制了你从某方向进入该路口所能进入的路口. 题解:1.对于方向的处理:将node多增加一维dir,通过一个const 字符数组 加 上dir_id函数 以及一个方 ...
- 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求最短路)
UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉 ...
- uva 816 - Abbott's Revenge(有点困难bfs迷宫称号)
是典型的bfs,但是,这个问题的目的在于读取条件的困难,而不是简单地推断,需要找到一种方法来读取条件.还需要想办法去推断每一点不能满足条件,继续往下走. #include<cstdio> ...
- UVa 816 Abbott的复仇(BFS)
寒假的第一道题目,在放假回家颓废了两天后,今天终于开始刷题了.希望以后每天也能多刷几道题. 题意:这道BFS题还是有点复杂的,给一个最多9*9的迷宫,但是每个点都有不同的方向,每次进入该点的方向不同, ...
- BFS求最短路 Abbottt's Revenge UVa 816
本题的题意是输入起点,朝向和终点,求一条最短路径(多解时任意输出一个即可) 本题的主要代码是bfs求解,就是以下代码中的slove的主要部分,通过起点按照路径的长度来寻找最短路径,输出最先到终点的一系 ...
- Abbott's Revenge UVA - 816 (输出bfs路径)
题目链接:https://vjudge.net/problem/UVA-816 题目大意: 有一个最多包含9*9 个交叉点的迷宫.输入起点,离开起点时的朝向和终点,求一条最短路(多解时任意输出 一个即 ...
随机推荐
- Oracl Over函数
Oracl Over函数 简介 在介绍Over之前, 必须提到开窗函数, 与 聚 合函数一样, 开窗函数也是对行集组进行聚合计算, 但是它不像普通聚合函数那样每组只返回一个值, 开窗函数可以为每组返回 ...
- shell第四篇(上)
第四篇了解Shell 命令执行流程图 {网中人大哥推荐参考Learning the Bash Shell, 2nd Edition,第 178页:中文版229页} Shell 从标准输入或脚本中读取的 ...
- nginx配置文件中的location理解
关于一些对location认识的误区 1. location 的匹配顺序是"先匹配正则,再匹配普通". 矫正: location 的匹配顺序其实是"先匹配普通,再匹配正则 ...
- curl与grep的使用
[root@nhserver1 ~]# curl -s www.163.com | grep hot_pop_js.js | sed 's/www.[[:digit:]]*.com/111/' ...
- appium问题整理
在刚进入appium的世界时,遇到无数的坑,趟过无数的浑水,现在整理一些常用的报错讯息,供大家参考 1.org.openqa.selenium.remote.UnreachableBrowserExc ...
- [DeeplearningAI笔记]改善深层神经网络_优化算法2.1_2.2_mini-batch梯度下降法
觉得有用的话,欢迎一起讨论相互学习~Follow Me 2.1 mini-batch gradient descent mini-batch梯度下降法 我们将训练数据组合到一个大的矩阵中 \(X=\b ...
- maven项目引入sqljdbc4 找不到包的完美 解决方案。
今天碰到了这个问题,解决了,顺便做一下记录.首先来 重现 一下这个问题,maven install报错,说 找不到这个包,但是其实 我已经安装了. 我们 再来 看看 maven本地仓库里面有 什么,这 ...
- Cypher查询语言--Neo4j 入门 (一)
目录 操作符 参数 标识符 注解 Start 通过id绑定点 通过id绑定关系 通过id绑定多个节点 所有节点 通过索引查询获取节点 通过索引查询获取关系 多个开始点 Cypher是一个描述性的图形 ...
- c#实现Word转换PNG图片
由于项目需要,经过一些大神的指导以及github,stackOverflow找资料,写了个这么个程序. 主要是因为word文档有特殊字体,特殊字体处理就要用到EnhMetaFileBits,即获取一页 ...
- MySQL用户授权与权限
MySQL权限如下表 权限名字 权限说明 Context CREATE 允许创建新的数据库和表 Databases, tables, or indexes DROP 允许删除现有数据库.表和视图 Da ...