UVA - 816 Abbott's Revenge(bfs)
题意:迷宫从起点走到终点,进入某点的朝向不同,可以出去的方向也不同,输出最短路。
分析:因为朝向决定接下来在该点可以往哪里走,所以每个点需要有三个信息:x,y,d(坐标和进入该点的朝向),所以将起点的下一个点当做初始状态
注意理解题意:进入交叉点的朝向与从哪个方向进交叉点正好相反
#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
typedef long long ll;
typedef unsigned long long llu;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {, , , -};
const int dc[] = {, , -, };
const int MOD = 1e9 + ;
const double pi = acos(-1.0);
const double eps = 1e-;
const int MAXN = + ;
const int MAXT = + ;
using namespace std;
char s[];
bool edge[][][][];
int dis[][][];
const char* a = "ESWN";//与数组dr,dc方向对应
const char* b = "LFR";
struct Node{
int x, y, d;//当前点的坐标,及进入该点的朝向
Node(){}
Node(int xx, int yy, int dd):x(xx), y(yy), d(dd){}
}num[][][];//记录该点的上一个点
int dir_id(char c){
return strchr(a, c) - a;
}
int turn_id(char c){
return strchr(b, c) - b;
}
bool judge(int x, int y){
return x >= && x <= && y >= && y <= ;
}
Node next(const Node&t, int turn){//turn与字符数组b下标对应
int dir = t.d;//向前走朝向不变
if(!turn){//向左走
dir = (dir + ) % ;//减1等价于加3
}
else if(turn == ){
dir = (dir + ) % ;
}
return Node(t.x + dr[dir], t.y + dc[dir], dir);
}
void print_ans(Node t, int tx, int ty, int dir){
stack<Node> st;
while(){
st.push(t);
if(dis[t.x][t.y][t.d] == ) break;
t = num[t.x][t.y][t.d];
}
st.push(Node(tx, ty, dir));
int cnt = ;
while(!st.empty()){
Node tmp = st.top();
st.pop();
++cnt;
if(cnt % == ) printf(" ");
printf(" (%d,%d)", tmp.x, tmp.y);
if(cnt % == ) printf("\n");
}
if(cnt % != ) printf("\n");
}
bool bfs(int sx, int sy, int dir, int ex, int ey){
memset(dis, -, sizeof dis);
queue<Node> q;
q.push(Node(sx, sy, dir));
dis[sx][sy][dir] = ;
int tx = sx - dr[dir];//迷宫起点
int ty = sy - dc[dir];
while(!q.empty()){
Node t = q.front();
q.pop();
if(t.x == ex && t.y == ey){
print_ans(t, tx, ty, dir);
return true;
}
for(int i = ; i < ; ++i){
Node v = next(t, i);
if(edge[t.x][t.y][t.d][i] && judge(v.x, v.y) && dis[v.x][v.y][v.d] < ){
dis[v.x][v.y][v.d] = dis[t.x][t.y][t.d] + ;
num[v.x][v.y][v.d] = t;
q.push(v);
}
}
}
return false;
}
int main(){
while(scanf("%s", s) == ){
if(strcmp(s, "END") == ) return ;
printf("%s\n", s);
memset(edge, , sizeof edge);
int sx, sy, ex, ey;
char dir;
scanf("%d%d %c%d%d", &sx, &sy, &dir, &ex, &ey);
int d = dir_id(dir);//进起点的下一个点的朝向
int nx = sx + dr[d];//起点的下一个位置
int ny = sy + dc[d];
int x;
while(scanf("%d", &x) == ){
if(x == ) break;
int y;
scanf("%d", &y);
while(scanf("%s", s) == ){
if(s[] == '*') break;
int tmp_dir = dir_id(s[]);
int len = strlen(s);
for(int i = ; i < len; ++i){
int tmp_turn = turn_id(s[i]);
edge[x][y][tmp_dir][tmp_turn] = ;
}
}
}
bool ok = bfs(nx, ny, d, ex, ey);//起点的下一个点因为已知,所以将其当为开始的点
if(!ok){
printf(" No Solution Possible\n");
}
}
return ;
}
UVA - 816 Abbott's Revenge(bfs)的更多相关文章
- UVa 816 Abbott的复仇(BFS)
寒假的第一道题目,在放假回家颓废了两天后,今天终于开始刷题了.希望以后每天也能多刷几道题. 题意:这道BFS题还是有点复杂的,给一个最多9*9的迷宫,但是每个点都有不同的方向,每次进入该点的方向不同, ...
- 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无法确定下一个结点,但对于没一个结点,它的 ...
- Uva 816 Abbott的复仇(三元组BFS + 路径还原)
题意: 有一个最多9*9个点的迷宫, 给定起点坐标(r0,c0)和终点坐标(rf,cf), 求出最短路径并输出. 分析: 因为多了朝向这个元素, 所以我们bfs的队列元素就是一个三元组(r,c,dir ...
- Uva 816 Abbott's Revenge(BFS)
#include<cstdio> #include<cstring> #include<vector> #include<queue> using na ...
- uva 816 abbott's revenge ——yhx
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAncAAAN5CAYAAABqtx2mAAAgAElEQVR4nOy9sY4jydKezVuoayhH0r
- UVa 439骑士的移动(BFS)
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- Uva - 816 - Abbott's Revenge
这个迷宫问题还是挺好玩的,多加了一个转向的问题,有些路口不同的进入方式会有不同的转向限制,这个会比较麻烦一点,所以定义结点结构体的时候需要加一个朝向dir.总体来说是一道BFS求最短路的问题.最后打印 ...
随机推荐
- MySQL : INSERT INTO SELECT
INSERT INTO wx_announcement_push ( title, content, STATUS, del_flag, user_login_name ) SELECT '大家好', ...
- vscode调试开发C/C++程序
https://www.cnblogs.com/TAMING/p/8560253.html
- JS中,跨域调用(本地)另一个项目的方法
IP地址,因为是本地的项目,所以我一开始写的是127.0.0.1...,但不对.应该写本机的IP地址才对!
- 爬虫(十五):Scrapy框架(二) Selector、Spider、Downloader Middleware
1. Scrapy框架 1.1 Selector的用法 我们之前介绍了利用Beautiful Soup.正则表达式来提取网页数据,这确实非常方便.而Scrapy还提供了自己的数据提取方法,即Selec ...
- 对于JAVA语言的一点理解
java作为一门面向对象的语言,现在常常被用于企业服务器端的后台开发.同时,C语言可能更多地是用于嵌入式的开发,所谓的嵌入式就是航天飞机上的设备软件之类的东西.但是,我逐渐发现,我们平时所说的java ...
- C/C++网络编程2——socket函数
本节主要介绍创建套接字的socket函数. #include <sys/socket.h> int socket(int domain, int type, int protocol); ...
- 使用CSS3动画属性实现各种旋转跳跃
Transform字面上就是变形,改变的意思.在CSS3中transform主要包括以下几种:旋转rotate.扭曲skew.缩放scale和移动translate以及矩阵变形matrix. tran ...
- Groovy轻松入门——通过与Java的比较,迅速掌握Groovy
转自 :Groovy轻松入门——通过与Java的比较,迅速掌握Groovy (更新于2008.10.18) 在前几篇文章中,我已经向大家介绍了Groovy是什么,学习Groovy的重要性等内容,还不了 ...
- VS2010解决闪退的方法
VS2010解决闪退的原因 前言 在利用vs2010编译器进行编写程序的时候程序结果无法看到,针对上述问题有如下两个解决方法: 方法1. 在程序结束之前(return之前)加 system(&quo ...
- MySQL操作之DML
目录 SQL语句的分类 DML语句 SQL语句的分类 DDL(Data Definition Languages)语句:数据定义语言.这些语句定义了不同的数据段. 数据库.表.列.索引等数据库对象的定 ...