题目

写这道题差点没把我气死,网上的好多题解看了半天结果是假的…

题目PDF

【分析】

利用队列实现广度搜索BFS来遍历图寻找最短路径。

用一个三元组(r, c, dir)表示“位于(r, c),面朝dir”这个状态。假设入口位置为(r0, c0),朝向为dir,则初始状态并不是(r0, c0, dir),而是(r1, c1, dir),其中,(r1, c1)是(r0, c0)沿着方向dir走一步之后的坐标。此处用d[r][c][dir]表示初始状态到(r, c, dir)的最短路长度,并且用p[r][c][dir]保存了状态(r, c, dir)在BFS树中的父结点。

在输入过程中,读取r0,c0,dir,并且计算出r1,c1即初始状态位置,读取终点位置r2,c2。读取交叉点的位置允许出去的方向,将朝向 dir 和转弯方向 turn 转化为编号03和02,并储存在has_edge数组中,其中has_edge[r][c][dir][turn]表示当前状态是(r, c, dir),是否可以沿着转弯方向turn行走。在BFS遍历的过程中,可以依据has_edge[r][c][dir][turn]判断位置(r, c, dir)是否可以这样转弯走到新状态。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e3+7;
const ll mod=2147483647;
struct node
{int x,y,dir;// 站在(r,c),面朝方向dir(0~3分别表示N, E, S, W)/*node(int x=0,int y=0,int dir=0){this->x=x;this->y=y;this->dir=dir;}*/node(int x=0, int y=0, int dir=0):x(x),y(y),dir(dir) {}
}father[10][10][4];//father[r][c][dir]表示了(r,c,dir)在BFS树中的父节点
int d[10][10][4];//用来累加起点到终点的距离
int has_edge[10][10][10][10];//保存每一个坐标的具体转向方式
const char* dirs="NESW";// 顺时针旋转
const char* turns="FLR";
int dir_id(char c){return strchr(dirs,c)-dirs;}//返回c在dirs的位置
int turn_id(char c){return strchr(turns,c)-turns;}
int x_0,x_1,y_0,y_1,x2,y2,dir;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {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.x+dx[dir],u.y+dy[dir],dir);
}
//判断坐标是否出界
bool check(int x,int y)
{return x>=1&&x<=9&&y>=1&&y<=9;
}
bool read_case()
{char s1[100],s2[100];//s1是指当前的流程,x0表示起始行,y0表示起始列,s2起始方向,x2表示目标行,y2表示目标列if(scanf("%s%d%d%s%d%d",s1,&x_0,&y_0,s2,&x2,&y2)!=6)return false;printf("%s\n",s1);dir=dir_id(s2[0]);//方向在字符串dirs中的位置x_1=x_0+dx[dir];//第一步之后的行坐标y_1=y_0+dy[dir];//第二步之后的列坐标memset(has_edge,0,sizeof has_edge);for(;;){int x,y;scanf("%d",&x);if(x==0)break;scanf("%d",&y);while(scanf("%s",s1)==1&&s1[0]!='*'){for(int i=1;i<=strlen(s1);++i)has_edge[x][y][dir_id(s1[0])][turn_id(s1[i])]=1;}}return true;
}
void print_ans(node u)
{ // 从目标结点逆序追溯到初始结点vector<node>nodes;for(;;){nodes.push_back(u);if(d[u.x][u.y][u.dir]==0)break;//说明找到了终点u=father[u.x][u.y][u.dir];}nodes.push_back(node(x_0,y_0,dir));int cnt=0;for(int i=nodes.size()-1;i>=0;i--){if(cnt%10==0)printf(" ");printf(" (%d,%d)", nodes[i].x, nodes[i].y);if((++cnt)%10==0)printf("\n");}if(nodes.size()%10!=0)printf("\n");
}
void solve()
{queue<node>q;memset(d,-1,sizeof d);//第一步之后,处于(2,1,N)的状态node u(x_1,y_1,dir);//走了一步之后的坐标d[u.x][u.y][u.dir]=0;q.push(u);while(!q.empty()){node u=q.front();q.pop();if(u.x==x2&&u.y==y2){print_ans(u);return ;}//判断当前坐标点,在当前转向的三个方向哪个是可以行使的?for(int i=0;i<3;i++){node v=walk(u,i);//v是u坐标行走一步之后的坐标,走到终点没有初始化,has_edge值为0,不进入循环if(has_edge[u.x][u.y][u.dir][i]&&check(v.x, v.y)&&d[v.x][v.y][v.dir]<0)//能走且为出界且没走过{d[v.x][v.y][v.dir] = d[u.x][u.y][u.dir] +1;//累加1,最后得出起点到终点的距离father[v.x][v.y][v.dir]=u;//表示v的父节点是uq.push(v);}}}printf("  No Solution Possible\n");
}
int main()
{while(read_case()){solve();}return 0;
}

UVA816 Abbott的复仇 Abbott's Revenge(final的BFS)(真•答案)相关推荐

  1. UVa816 例题 6-14 Abbott的复仇 (Abbott's Revenge,ACM/ICPC World Finals 2000)

    原题链接: UVa-816 题目大意: 模有一个最多包含9*9个交叉点的迷宫.输入起点.离开起点时的朝向和终点,求一条最短路径.(具体题目参考原题和紫书) 解题思路: 本题是一道用BFS求最短路径的迷 ...

  2. [uva816]AbbottsRevenge Abbott的复仇(经典迷宫BFS)

    这题思路就普通的BFS加上一个维度朝向,主要是要注意输入,输出,以及细节的处理 #include<cstdio> #include<cstring> #include<q ...

  3. (翻译)复仇模式(Revenge)

    问题概述   人们喜欢以其人之道还治其人之身[1]. 用途 用于鼓励使用复仇方式增强游戏可玩性:在游戏或挑战中击败朋友: 如果复仇行为以不和收场,且结局并不是皆大欢喜,不要使用本模式[2]. 说明   ...

  4. 祖玛的复仇 Zuma's Revenge 无限人的 修改

    今天我的GF玩那游戏,苦于游戏太难,又不想失去游戏乐趣,让我帮她弄个无限人,结果就查了一下  原来又8个地址是标记人数的, 而且是靠2个指针来控制的,所以把地址给你们发出来以供其他朋友使用, 基地址0 ...

  5. 我感觉ae比较难用,就是做这种画中画的视频,final cut pro真香

    直接找一个底板 一层一层往上碟就行了呗

  6. 【算法】BFS刷题总结

    姊妹篇(DFS) 目录 一.入门级 P1747 好奇怪的游戏 TRDD got lost again 二.进阶 final的BFS Abbott's Revenge 一.入门级 P1747 好奇怪的游 ...

  7. 算法竞赛入门经典(第二版)-刘汝佳-第六章 数据结构基础 习题(12/14)

    文章目录 说明 习题 习6-1 UVA 673 平衡的括号 习6-2 UVA 712 S - 树 习6-3 UVA 536 二叉树重建 习6-4 UVA 439 骑士的移动 习6-5 UVA 1600 ...

  8. 算法竞赛入门竞赛 入门经典 第六章 个人记录

    UVa 210 并行程序模拟(放弃 || 待补) 没看懂题意,但是有百度了一下duque 算是对duque有了一个大致的认识和了解 当然也有尝试. 本来想着去hdu找一些duque的题 结果 好像可以 ...

  9. 马斯克、吴恩达等27人出镜:AI可能成为不朽独裁者,人类就像蚂蚁束手就擒

    BOT or NOT? 在刚刚上线的AI纪录片<你信任这台电脑吗?>(Do you trust this computer?)中,马斯克又发出警告: AI可能会成为不朽的独裁者. 马斯克指 ...

最新文章

  1. ecshop数据表结构说明
  2. 活动目录向DNS注册SRV记录不成功的原因
  3. python输入一个字母_python – Tkinter输入的第一个字母
  4. 7-45 航空公司VIP客户查询 (25 分)(思路+详解+map用法解释+超时解决)兄弟们来呀冲压呀呀呀呀
  5. si_meminfo获取当前系统物理内存使用情况
  6. 蔡高厅老师 - 高等数学阅读笔记 - 07 - 函数的微分 - 微分中值定理 罗尔、拉格朗日中值定理 (31、32、33、34、35)
  7. 2018年技术上该怎样努力
  8. javaScript = == ===的区别
  9. 台达变频器485通讯接线图_台达变频器RS485通讯设置
  10. JS核心之封装继承多态(一)
  11. Java实现微信红包随机金额算法
  12. Java锁与线程的那些“不可描述”的事儿
  13. 2018ICPC网络赛(焦作站)E题题解
  14. C#效验身份证号是否正确
  15. SangforAC(深信服)Web单点登录
  16. Terracotta Server集群
  17. 读《经济学通识》薛兆丰
  18. matlab 格兰杰,matlab非参数的格兰杰因果分析
  19. Matlab从txt第二行开始读,MATLAB小技:从文本数据第n行开始读取
  20. 领域研究 | IL-1B与先天免疫

热门文章

  1. 12个深度学习面试问题
  2. 链表问题6——环形单链表的约瑟夫问题(初阶)
  3. 栈与队列2——两个栈组成队列
  4. SpringBoot实战(四)之使用JDBC和Spring访问数据库
  5. jupyter的下载安装
  6. OpenStack入门修炼之实战--实现阿里云ESC多FLAT网络(21)
  7. ConcurrentDictionary线程不安全么,你难道没疑惑,你难道弄懂了么?
  8. ASP.NET Web API 实现客户端Basic(基本)认证 之简单实现
  9. 用Python实现一个简单的线程池
  10. java数组出现次数最多的数_找出数组中出现次数最多的那个数——主元素问题...