题意:https://www.nitacm.com/problem_show.php?pid=2266

vis记【x】【y】【dir】三个状态就行。

引用:https://blog.csdn.net/qq_37451344/article/details/80243077

 #include<string.h>
#include<stdio.h>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
int x1,y1;
int n,m;
char mat[][];
int vis[][][];
int f[][]={,,,-,-,,,};//左,右,上,下;
struct node{
int x,y;//坐标
int ff;//方向
int temp;
};
int judge(int a,int b,int c,int d)
{//判断符不符合拐弯的条件
if(mat[a][b]=='#'&&mat[c][d]=='#')
{
return ;
}
return ;
}
void bfs()
{
node s,t;
queue<node>q;
s.x=x1;
s.y =y1;
s.temp=;
s.ff=-;//起始方向为-1
vis[x1][y1][]=vis[x1][y1][]=vis[x1][y1][]=vis[x1][y1][]=;
q.push(s);
while(!q.empty())
{
int flag=;
t=q.front();
q.pop();
if((t.x==||t.x==n-||t.y==||t.y==m-))
{//到达边缘
printf("%d\n",t.temp );
return;
}
int x2,x3,y2,y3;
if(t.ff==||t.ff==)
{//当从左,或从右到达t点时,判断上下方向能不能拐弯
x2=t.x+;
y2=t.y;
x3=t.x-;
y3=t.y;
if(judge(x2,y2,x3,y3))
{//如果能拐
for(int i=;i<;i++)
{//向上或向下拐
s.x=t.x+f[i][];
s.y=t.y+f[i][];
s.temp=t.temp+;
s.ff=i;//记录s点从哪个方向过来的
if(s.x>=n||s.x<||s.y>=m||s.y<||vis[s.x][s.y][s.ff]||mat[s.x][s.y]=='#')
continue;
vis[s.x][s.y][i]=;
q.push(s);
}
}
else flag=;//不能拐,标记
} else if(t.ff==||t.ff==)
{//从上或下到达t点时,判断左右方向能不能拐弯
x2=t.x;
y2=t.y+;
x3=t.x;
y3=t.y-;
if(judge(x2,y2,x3,y3))
{//能拐
for(int i=;i<;i++)
{//就两个方向,向左或向右拐
s.x=t.x+f[i][];
s.y=t.y+f[i][];
s.temp=t.temp+;
s.ff=i;
if(s.x>=n||s.x<||s.y>=m||s.y<||vis[s.x][s.y][s.ff]||mat[s.x][s.y]=='#')
continue;
vis[s.x][s.y][s.ff]=;
q.push(s);
}
}
else flag=;//不能拐,标记
} else if(t.ff==-)
{//这是起点的时候,任意方向都可以
for(int i=;i<;i++)
{
s.x=t.x+f[i][];
s.y=t.y+f[i][];
s.temp=t.temp+;
s.ff=i;
if(s.x>=n||s.x<||s.y>=m||s.y<||vis[s.x][s.y][s.ff]||mat[s.x][s.y]=='#')
continue;
vis[s.x][s.y][s.ff]=;
q.push(s);
}
} if(flag==)
{//如果不能拐,就按原方向前进
s.x=t.x+f[t.ff][];
s.y=t.y+f[t.ff][];
s.temp=t.temp+;
s.ff=t.ff;
if(s.x>=n||s.x<||s.y>=m||s.y<||vis[s.x][s.y][s.ff]||mat[s.x][s.y]=='#')
continue;
vis[s.x][s.y][s.ff]=;
q.push(s);
}
}
printf("-1\n");
return;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(vis,,sizeof(vis));
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
scanf("%s",mat[i]);
for(int i=;i<n;i++)
for(int j=;j<m;j++)
{
if(mat[i][j]=='@')
{//起点
x1=i;y1=j;
}
}
if(x1==||x1==n-||y1==||y1==m-)
{//起点在边缘,就是0
printf("0\n");
continue;
}
bfs();
}
return ;
}

Escape(多记一个方向状态的BFS)迷宫逃脱的更多相关文章

  1. HDU 4634 Swipe Bo 状态压缩+BFS最短路

    将起始点.终点和钥匙统一编号,预处理: 1.起始点到所有钥匙+终点的最短路 2.所有钥匙之间两两的最短路 3.所有钥匙到终点的最短路 将起始点和所有钥匙四方向出发设为起点BFS一遍,求出它到任意点任意 ...

  2. HDU4845(SummerTrainingDay02-C 状态压缩bfs)

    拯救大兵瑞恩 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Subm ...

  3. 胜利大逃亡(续)(状态压缩bfs)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  4. Pots POJ - 3414【状态转移bfs+回溯】

    典型的倒水问题: 即把两个水杯的每种状态视为bfs图中的点,如果两种状态可以转化,即可认为二者之间可以连一条边. 有3种倒水的方法,对应2个杯子,共有6种可能的状态转移方式.即相当于图中想走的方法有6 ...

  5. 记一个社交APP的开发过程——基础架构选型(转自一位大哥)

    记一个社交APP的开发过程——基础架构选型 目录[-] 基本产品形态 技术选型 最近两周在忙于开发一个社交App,因为之前做过一点儿社交方面的东西,就被拉去做API后端了,一个人头一次完整的去搭这么一 ...

  6. 【GDOI2015】 推箱子 状态压缩+bfs

    请注意$8$是一个美妙的数字 考虑到$8\times 8=64$,而一个unsigned long long是$64$位的,所以考虑用一个$01$状态存储箱子.考虑到箱子能转动,那么四种情况都存一下就 ...

  7. 好一个Time_Wait状态(TCP/IP)

    首先简单介绍一下Time_Wait是个什么鬼: 在TCP/IP协议中,我们都知道有三次握手四次挥手的过程,先来一个简单的图: 各个状态和基本的过程想必了解过TCP/IP协议的人都清楚,本次介绍的主题只 ...

  8. 每天一个 HTTP 状态码 前言

    前前言 在重新开始写博文(其实大多也就最多算是日常笔记小结)之际,就想着从短小精悍的文章入手,就想到了 HTTP 状态码.另外,记得很久之前,看过一个<每天一个 Linux 命令>系列文章 ...

  9. [Swust OJ 1023]--Escape(带点其他状态的BFS)

    解题思路:http://acm.swust.edu.cn/problem/1023/ Time limit(ms): 5000 Memory limit(kb): 65535     Descript ...

随机推荐

  1. devstack 使用openstack命令报错 The request you have made requires authentication. (HTTP 401) Missing value auth-url required for auth plugin password

    关联错误: The request you have made requires authentication. (HTTP 401) (Request-ID: req-88ad2cba-0f2d-4 ...

  2. Ubuntu 14.04 下安装redis后运行redis-cli 报出redis Connection refused错误【已解决】

    在运行redis-cli运行后爆出错误,看了网上的都没有用例如:改ip,注释bind 127.0.0.1,或者是先运行./redis-server redis.conf,都没有用 只需要: 找到red ...

  3. springboot+mybatis+druid+sqlite/mysql/oracle

    搭建springboot+mybatis+druid+sqlite/mysql/oracle附带测试 1.版本 springboot2.1.6 jdk1.8 2.最简springboot环境 http ...

  4. JAVA基础知识|Socket

    一.什么是Socket? Socket本身并不是协议,是一套完成TCP.UDP协议的调用接口(API),通过socket我们才能使用TCP/IP协议(JAVA基础知识|TCP/IP协议).Socket ...

  5. 关系型数据库的树形结构查询(Oracle、Postgres)

    Oracle : start with… connect by 的用法.语法:select * from table [where 条件1] connect by[条件2] start with[条件 ...

  6. 消息中间件MQ

    消息中间件MQ:为方便预览,将思维导图上传至印象笔记,博客园直接上传图片受限于图片大小 https://app.yinxiang.com/shard/s24/nl/27262531/c3e137a5- ...

  7. Java实现单例的5种方式

    1. 什么是单例模式 单例模式指的是在应用整个生命周期内只能存在一个实例.单例模式是一种被广泛使用的设计模式.他有很多好处,能够避免实例对象的重复创建,减少创建实例的系统开销,节省内存. 2. 单例模 ...

  8. Parameter 'list1' not found. Available parameters are [list] 解析

    在使用foreach语句时会经常报Parameter ‘ordersList’ not found. Available parameters are [list] 解析这个错误,造成这个错误的主要原 ...

  9. java课后实验性问题6

    1.继承条件下的构造方法调用. class Grandparent { public Grandparent(){ System.out.println("GrandParent Creat ...

  10. 如何丧心病狂的使用python爬虫读小说

    写在前边 其实一直想入门python很久了,慕课网啊,菜鸟教程啊python的基础的知识被我翻了很多遍了,但是一直没有什么实践.刚好,这两天被别人一直安利一本小说<我可能修的是假仙>,还在 ...