题意: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. 使用scp上传ssh公钥到服务器

    $ scp ~/.ssh/id_rsa.pub root@xxx.xxx.xxx.xxx:.ssh/id_rsa.pub $ ssh root@xxx.xxx.xxx.xxx $ cat ~/.ssh ...

  2. 7.26T3小游戏

    小游戏 题目描述 有一个简单的小游戏.游戏的主人公是一个勇士,他要穿过一片黑森林,去 解救公主.黑森林的地图可以用一张 V 个点.E 条边的无向图来描述,起点是 1 号点,终点是 V 号点.勇士从起点 ...

  3. Raspberry Pi 摄像头模块入门

    目录 一.摄像头模块安装 二.使用命令控制摄像头 三.使用Python程序控制摄像头 四.基于vlc的Raspberry Pi摄像头实时监控 参考资料 Raspberry Pi提供了摄像头模块的接口, ...

  4. adb的一些命令

    adb pull <手机路径> <本机路径> 从手机中拉取信息到本地电脑上 adb push <本机路径> <手机路径> 从本地电脑推送信息到手机上

  5. BufferedWriter中write与close函数使用

    BufferedWriter 是一个缓冲字符输出流,可以将要输出的内容先缓冲到一个字符数组中,等字符数组满了才一次性写到输出流内,默认的字符数组长度为8192.使用BufferedWriter 时需要 ...

  6. 外部连接mysql docker容器异常

    为了方便,使用python测试连接mysql容器 脚本内容非常简单 #!/usr/bin/python3 import pymysql conn=pymysql.connect(host=,passw ...

  7. Kotlin入门-文件读写操作

    转 https://blog.csdn.net/aqi00/article/details/83241762 Java的文件处理用到了io库java.io,该库虽然功能强大,但是与文件内容的交互还得通 ...

  8. C++ nth_element greater

    #include <iostream>#include <algorithm>#include <deque>#include <vector>#inc ...

  9. 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_12-webpack研究-webpack安装

    npm默认安装配置的路径配置在nodejs的node_modules目录 j加上 -g 就是全局安装 后面只写webpack默认安装的是最新版本 指定版本号 视频中建议指定版本号进行安装

  10. Cloudera Manager 概念

    cloudera公司发布的CDH集群,使用Cloudera Manager来管理整个集群,使用过程中主要涉及到几个关键概念:cluster.service.role.host.直接上图,直观理解几个概 ...