UVA816 Abbott的复仇 Abbott's Revenge(final的BFS)(真•答案)
题目
写这道题差点没把我气死,网上的好多题解看了半天结果是假的…
题目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)(真•答案)相关推荐
- UVa816 例题 6-14 Abbott的复仇 (Abbott's Revenge,ACM/ICPC World Finals 2000)
原题链接: UVa-816 题目大意: 模有一个最多包含9*9个交叉点的迷宫.输入起点.离开起点时的朝向和终点,求一条最短路径.(具体题目参考原题和紫书) 解题思路: 本题是一道用BFS求最短路径的迷 ...
- [uva816]AbbottsRevenge Abbott的复仇(经典迷宫BFS)
这题思路就普通的BFS加上一个维度朝向,主要是要注意输入,输出,以及细节的处理 #include<cstdio> #include<cstring> #include<q ...
- (翻译)复仇模式(Revenge)
问题概述 人们喜欢以其人之道还治其人之身[1]. 用途 用于鼓励使用复仇方式增强游戏可玩性:在游戏或挑战中击败朋友: 如果复仇行为以不和收场,且结局并不是皆大欢喜,不要使用本模式[2]. 说明 ...
- 祖玛的复仇 Zuma's Revenge 无限人的 修改
今天我的GF玩那游戏,苦于游戏太难,又不想失去游戏乐趣,让我帮她弄个无限人,结果就查了一下 原来又8个地址是标记人数的, 而且是靠2个指针来控制的,所以把地址给你们发出来以供其他朋友使用, 基地址0 ...
- 我感觉ae比较难用,就是做这种画中画的视频,final cut pro真香
直接找一个底板 一层一层往上碟就行了呗
- 【算法】BFS刷题总结
姊妹篇(DFS) 目录 一.入门级 P1747 好奇怪的游戏 TRDD got lost again 二.进阶 final的BFS Abbott's Revenge 一.入门级 P1747 好奇怪的游 ...
- 算法竞赛入门经典(第二版)-刘汝佳-第六章 数据结构基础 习题(12/14)
文章目录 说明 习题 习6-1 UVA 673 平衡的括号 习6-2 UVA 712 S - 树 习6-3 UVA 536 二叉树重建 习6-4 UVA 439 骑士的移动 习6-5 UVA 1600 ...
- 算法竞赛入门竞赛 入门经典 第六章 个人记录
UVa 210 并行程序模拟(放弃 || 待补) 没看懂题意,但是有百度了一下duque 算是对duque有了一个大致的认识和了解 当然也有尝试. 本来想着去hdu找一些duque的题 结果 好像可以 ...
- 马斯克、吴恩达等27人出镜:AI可能成为不朽独裁者,人类就像蚂蚁束手就擒
BOT or NOT? 在刚刚上线的AI纪录片<你信任这台电脑吗?>(Do you trust this computer?)中,马斯克又发出警告: AI可能会成为不朽的独裁者. 马斯克指 ...
最新文章
- ecshop数据表结构说明
- 活动目录向DNS注册SRV记录不成功的原因
- python输入一个字母_python – Tkinter输入的第一个字母
- 7-45 航空公司VIP客户查询 (25 分)(思路+详解+map用法解释+超时解决)兄弟们来呀冲压呀呀呀呀
- si_meminfo获取当前系统物理内存使用情况
- 蔡高厅老师 - 高等数学阅读笔记 - 07 - 函数的微分 - 微分中值定理 罗尔、拉格朗日中值定理 (31、32、33、34、35)
- 2018年技术上该怎样努力
- javaScript = == ===的区别
- 台达变频器485通讯接线图_台达变频器RS485通讯设置
- JS核心之封装继承多态(一)
- Java实现微信红包随机金额算法
- Java锁与线程的那些“不可描述”的事儿
- 2018ICPC网络赛(焦作站)E题题解
- C#效验身份证号是否正确
- SangforAC(深信服)Web单点登录
- Terracotta Server集群
- 读《经济学通识》薛兆丰
- matlab 格兰杰,matlab非参数的格兰杰因果分析
- Matlab从txt第二行开始读,MATLAB小技:从文本数据第n行开始读取
- 领域研究 | IL-1B与先天免疫
热门文章
- 12个深度学习面试问题
- 链表问题6——环形单链表的约瑟夫问题(初阶)
- 栈与队列2——两个栈组成队列
- SpringBoot实战(四)之使用JDBC和Spring访问数据库
- jupyter的下载安装
- OpenStack入门修炼之实战--实现阿里云ESC多FLAT网络(21)
- ConcurrentDictionary线程不安全么,你难道没疑惑,你难道弄懂了么?
- ASP.NET Web API 实现客户端Basic(基本)认证 之简单实现
- 用Python实现一个简单的线程池
- java数组出现次数最多的数_找出数组中出现次数最多的那个数——主元素问题...