题意: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. 绕过本机DNS缓存

    --转载注明来源 http://www.cnblogs.com/sysnap/ 0x1 背景 往HOST文件添加127.0.0.1  www.baidu.com, 可以劫持百度的域名.病毒经常篡改HO ...

  2. 写给新手看的 MyBatis 入门

    目录 MyBatis 使用前的准备 什么是 MyBatis 使用Maven 进行 MyBatis 开发环境搭建 MyBatis 入门 项目整体结构一览 MyBatis 的简单生命周期 1.获取 Sql ...

  3. 【C++】插值函数代码分析学习

    插值函数代码分析学习,用的CImage类load图像. // Imagejoint.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #inc ...

  4. Java同步数据结构之Map概述及ConcurrentSkipListMap原理

    引言 前面介绍了CopyOnWriteArraySet,本来接着是打算介绍ConcurrentSkipListSet,无耐ConcurrentSkipListSet的内部实现其实是依赖一个Concur ...

  5. kotlin 修饰符

    在kotlin中有四种修饰符: private 仅在类的内部使用 protected类似private,但在子类中可以访问 internal任何在模块内部类都可以访问 public:任何类都可以访问

  6. centos7 mysql 启动mysqld.service - SYSV: MySQL database server错误

    1.启动命令 systemctl start mysqld.service 或者 /etc/init.d/mysqld start   结果同样的错误 2.错误是: Job for mysqld.se ...

  7. 一个BADI中实施多个Implementation

    转自:https://blog.csdn.net/zhongguomao/article/details/76251407 业务场景:例如我们需要对国家的税率做一个增强,以完成某种业务运算,但是每个国 ...

  8. 陷门函数Trapdoor Function

    陷门函数:正向计算是很容易的,但若要有效的执行反向计算则必须要知道一些secret/knowledge/trapdoor(知识?),也称为伪随机置换,可用于构造公钥密码系统. 若 f 为陷门函数,则 ...

  9. 如何用最快的速度读出大小为10G的文件的行数?弄懂 python 的迭代器

    with open('rm_keys.txt', 'r', encoding = 'utf-8') as f: count = 0 for line in f: 7 count += 1 print( ...

  10. 324rfwrtg5gft8oywtfbserkufgs

    324rfwrtg5gft8oywtfbserkufgs (tester.inf.nano)