time limit per test3 seconds

memory limit per test256 megabytes

inputstandard input

outputstandard output

Theseus has just arrived to Crete to fight Minotaur. He found a labyrinth that has a form of a rectangular field of size n × m and consists of blocks of size 1 × 1.

Each block of the labyrinth has a button that rotates all blocks 90 degrees clockwise. Each block rotates around its center and doesn’t change its position in the labyrinth. Also, each block has some number of doors (possibly none). In one minute, Theseus can either push the button in order to rotate all the blocks 90 degrees clockwise or pass to the neighbouring block. Theseus can go from block A to some neighbouring block B only if block A has a door that leads to block B and block B has a door that leads to block A.

Theseus found an entrance to labyrinth and is now located in block (xT, yT) — the block in the row xT and column yT. Theseus know that the Minotaur is hiding in block (xM, yM) and wants to know the minimum number of minutes required to get there.

Theseus is a hero, not a programmer, so he asks you to help him.

Input

The first line of the input contains two integers n and m (1 ≤ n, m ≤ 1000) — the number of rows and the number of columns in labyrinth, respectively.

Each of the following n lines contains m characters, describing the blocks of the labyrinth. The possible characters are:

«+» means this block has 4 doors (one door to each neighbouring block);

«-» means this block has 2 doors — to the left and to the right neighbours;

«|» means this block has 2 doors — to the top and to the bottom neighbours;

«^» means this block has 1 door — to the top neighbour;

«>» means this block has 1 door — to the right neighbour;

«<» means this block has 1 door — to the left neighbour;

«v» means this block has 1 door — to the bottom neighbour;

«L» means this block has 3 doors — to all neighbours except left one;

«R» means this block has 3 doors — to all neighbours except right one;

«U» means this block has 3 doors — to all neighbours except top one;

«D» means this block has 3 doors — to all neighbours except bottom one;

«*» means this block is a wall and has no doors.

Left, right, top and bottom are defined from representing labyrinth as a table, where rows are numbered from 1 to n from top to bottom and columns are numbered from 1 to m from left to right.

Next line contains two integers — coordinates of the block (xT, yT) (1 ≤ xT ≤ n, 1 ≤ yT ≤ m), where Theseus is initially located.

Last line contains two integers — coordinates of the block (xM, yM) (1 ≤ xM ≤ n, 1 ≤ yM ≤ m), where Minotaur hides.

It’s guaranteed that both the block where Theseus starts and the block where Minotaur is hiding have at least one door. Theseus and Minotaur may be initially located at the same block.

Output

If Theseus is not able to get to Minotaur, then print -1 in the only line of the output. Otherwise, print the minimum number of minutes required to get to the block where Minotaur is hiding.

Examples

input

2 2

+*

*U

1 1

2 2

output

-1

input

2 3

<><

<>

1 1

2 1

output

4

Note

Assume that Theseus starts at the block (xT, yT) at the moment 0.

【题解】



一道广搜题;

要预处理出每个方块在旋转n(1..4)次之后能通向临近的哪些点;

->结构体 can[x][y][旋转次数].up left right down

->别用数字代替方向0 0不然会晕。

然后用个flag数组判重下状态就好;

广搜的时候多了个旋转所有的方格的转移;

->有点像在4张图上做最短路;

感觉挺简单的。

代码有点长

#include <cstdio>
#include <queue> using namespace std; const int MAXN = 1050; struct abc
{
bool up, down, left, right;
}; struct abcd
{
int step, zhuangtai,x,y;
}; int n, m,xt,yt,xm,ym;
abc can[MAXN][MAXN][4];
queue <abcd> dl;
bool flag[MAXN][MAXN][4];
char s[MAXN]; bool inrange(int x, int y)
{
if (x <1 || x>n)
return false;
if (y<1 || y>m)
return false;
return true;
} bool judge(int x, int y)
{
return (x == xm && y == ym);
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
{
scanf("%s", s);
for (int j = 1;j <= m;j++)
switch (s[j-1])
{
case '+':
{
for (int l = 0;l <= 3;l++)
for (int k = 0; k <= 3; k++)
{
can[i][j][l].up = true;
can[i][j][l].down = true;
can[i][j][l].left = true;
can[i][j][l].right = true;
}
break;
}
case '-':
{
can[i][j][0].left = true;
can[i][j][0].right = true;
can[i][j][1].up = true;
can[i][j][1].down = true;
can[i][j][2].left = true;
can[i][j][2].right = true;
can[i][j][3].up = true;
can[i][j][3].down = true;
break;
}
case'|':
{
can[i][j][0].up = true;
can[i][j][0].down = true;
can[i][j][1].left = true;
can[i][j][1].right = true;
can[i][j][2].up = true;
can[i][j][2].down = true;
can[i][j][3].left = true;
can[i][j][3].right = true;
break;
}
case'^':
{
can[i][j][0].up = true;
can[i][j][1].right = true;
can[i][j][2].down = true;
can[i][j][3].left = true;
break;
}
case'>':
{
can[i][j][0].right = true;
can[i][j][1].down = true;
can[i][j][2].left = true;
can[i][j][3].up = true;
break;
}
case '<':
{
can[i][j][2].right = true;
can[i][j][3].down = true;
can[i][j][0].left = true;
can[i][j][1].up = true;
break;
}
case 'v':
{
can[i][j][3].right = true;
can[i][j][0].down = true;
can[i][j][1].left = true;
can[i][j][2].up = true;
break;
}
case 'L':
{
can[i][j][0].up = true;
can[i][j][0].right = true;
can[i][j][0].down = true;
can[i][j][1].left = true;
can[i][j][1].right = true;
can[i][j][1].down = true;
can[i][j][2].up = true;
can[i][j][2].left = true;
can[i][j][2].down = true;
can[i][j][3].up = true;
can[i][j][3].left = true;
can[i][j][3].right = true;
break;
}
case 'R':
{
can[i][j][2].up = true;
can[i][j][2].right = true;
can[i][j][2].down = true;
can[i][j][3].left = true;
can[i][j][3].right = true;
can[i][j][3].down = true;
can[i][j][0].up = true;
can[i][j][0].left = true;
can[i][j][0].down = true;
can[i][j][1].up = true;
can[i][j][1].left = true;
can[i][j][1].right = true;
break;
}
case 'U':
{
can[i][j][3].up = true;
can[i][j][3].right = true;
can[i][j][3].down = true;
can[i][j][0].left = true;
can[i][j][0].right = true;
can[i][j][0].down = true;
can[i][j][1].up = true;
can[i][j][1].left = true;
can[i][j][1].down = true;
can[i][j][2].up = true;
can[i][j][2].left = true;
can[i][j][2].right = true;
break;
}
case 'D':
{
can[i][j][1].up = true;
can[i][j][1].right = true;
can[i][j][1].down = true;
can[i][j][2].left = true;
can[i][j][2].right = true;
can[i][j][2].down = true;
can[i][j][3].up = true;
can[i][j][3].left = true;
can[i][j][3].down = true;
can[i][j][0].up = true;
can[i][j][0].left = true;
can[i][j][0].right = true;
break;
}
case '*':
{
//wall
break;
}
}
}
scanf("%d%d", &xt, &yt);
scanf("%d%d", &xm, &ym);
flag[xt][yt][0] = true;
if (flag[xm][ym][0])
{
puts("0");
return 0;
}
abcd temp;
temp.step = 0;
temp.zhuangtai = 0;
temp.x = xt, temp.y = yt;
dl.push(temp);
while (!dl.empty())
{
abcd h = dl.front();
dl.pop();
int a0 = h.x, b0 = h.y, s = h.step, zt = h.zhuangtai;
int tempa0, tempb0;
//up
tempa0 = a0 - 1; tempb0 = b0;
if (inrange(tempa0, tempb0))
{
if (can[tempa0][tempb0][zt].down && can[a0][b0][zt].up)
{
if (!flag[tempa0][tempb0][zt])
{
flag[tempa0][tempb0][zt] = true;
abcd temph;
temph.x = tempa0, temph.y = tempb0, temph.step = s + 1, temph.zhuangtai = zt;
if (judge(tempa0, tempb0))
{
printf("%d\n", s + 1);
return 0;
}
dl.push(temph);
}
}
} //down
tempa0 = a0 +1; tempb0 = b0;
if (inrange(tempa0, tempb0))
{
if (can[tempa0][tempb0][zt].up && can[a0][b0][zt].down)
{
if (!flag[tempa0][tempb0][zt])
{
flag[tempa0][tempb0][zt] = true;
abcd temph;
temph.x = tempa0, temph.y = tempb0, temph.step = s + 1, temph.zhuangtai = zt;
if (judge(tempa0, tempb0))
{
printf("%d\n", s + 1);
return 0;
}
dl.push(temph);
}
}
} //left
tempa0 = a0; tempb0 = b0-1;
if (inrange(tempa0, tempb0))
{
if (can[tempa0][tempb0][zt].right && can[a0][b0][zt].left)
{
if (!flag[tempa0][tempb0][zt])
{
flag[tempa0][tempb0][zt] = true;
abcd temph;
temph.x = tempa0, temph.y = tempb0, temph.step = s + 1, temph.zhuangtai = zt;
if (judge(tempa0, tempb0))
{
printf("%d\n", s + 1);
return 0;
}
dl.push(temph);
}
}
} //right
tempa0 = a0; tempb0 = b0 + 1;
if (inrange(tempa0, tempb0))
{
if (can[tempa0][tempb0][zt].left && can[a0][b0][zt].right)
{
if (!flag[tempa0][tempb0][zt])
{
flag[tempa0][tempb0][zt] = true;
abcd temph;
temph.x = tempa0, temph.y = tempb0, temph.step = s + 1, temph.zhuangtai = zt;
if (judge(tempa0, tempb0))
{
printf("%d\n", s + 1);
return 0;
}
dl.push(temph);
}
}
} //change
tempa0 = a0; tempb0 = b0;
int newzt = (zt + 1) % 4;
if (!flag[tempa0][tempb0][newzt])
{
flag[tempa0][tempb0][newzt] = true;
abcd temph;
temph.x = tempa0, temph.y = tempb0, temph.step = s + 1, temph.zhuangtai = newzt;
dl.push(temph);
}
}
puts("-1");
return 0;
}

【25.93%】【676D】Theseus and labyrinth的更多相关文章

  1. 剑指Offer:合并两个排序的链表【25】

    剑指Offer:合并两个排序的链表[25] 题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 题目分析 每次都是比较箭头节点,把小节点连接到已经合 ...

  2. JAVA 基础编程练习题25 【程序 25 求回文数】

    25 [程序 25 求回文数] 题目:一个 5 位数,判断它是不是回文数.即 12321 是回文数,个位与万位相同,十位与千位相同. package cskaoyan; public class cs ...

  3. UI设计师零基础入门到精通精品视频教程【155课高清完整版】

    [福吧资源网分享]课程是非常完整的,也是非常零基础的,适合任何学员,有需要的可以下载看看!课程目录:第1章 Adobe Photoshop CS6课时1 Adobe Photoshop CS6入门基础 ...

  4. 【Android】【录音】Android录音--AudioRecord、MediaRecorder

    [Android][录音]Android录音--AudioRecord.MediaRecorder Android提供了两个API用于实现录音功能:android.media.AudioRecord. ...

  5. 【Xamarin开发 Android 系列 3】循序渐进的学习顺序

    原文:[Xamarin开发 Android 系列 3]循序渐进的学习顺序 指定合理的学习步骤,将各个技术点进行强化.慢慢 的就从点到线 到面的飞跃,一切仅仅是时间问题,开始前,请记住,学习是最佳的投资 ...

  6. 【iScroll源码学习01】准备阶段 - 叶小钗

    [iScroll源码学习01]准备阶段 - 叶小钗 时间 2013-12-29 18:41:00 博客园-原创精华区 原文  http://www.cnblogs.com/yexiaochai/p/3 ...

  7. 【WC2001】【cogs358】高性能计算机(动态规划)

    [WC2001][cogs358]高性能计算机(动态规划) ##题面 [问题描述] 现在有一项时间紧迫的工程计算任务要交给你--国家高性能并行计算机的主管工程师--来完成.为了尽可能充分发挥并行计算机 ...

  8. 【Python】【容器 | 迭代对象 | 迭代器 | 生成器 | 生成器表达式 | 协程 | 期物 | 任务】

    Python 的 asyncio 类似于 C++ 的 Boost.Asio. 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知. Asyn ...

  9. 【Python】【IO】

    # [[IO]] # [文件读写] '''读写文件是最常见的IO操作.Python内置了读写文件的函数,用法和C是兼容的.读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现 ...

随机推荐

  1. oracle Transactional

    从shutdown transactional命令发布起, 禁止建立任何新的oracle连接. 从shutdown transactional命令发布起,禁止启动任何新的事务. 一旦数据库上所有的活动 ...

  2. centos6.5后台进程的切换

    1.运行.sh文件 直接用./sh 文件就可以运行,但是如果想后台运行,即使关闭当前的终端也可以运行的话,需要nohup命令和&命令. (1)&命令 功能:加在一个命令的最后,可以把这 ...

  3. 容器云平台使用体验:数人云Crane(续)

    数人云在9月6日开通了容器管理面板Crane的试用活动,这是国内首个基于DockerSwarmKit的容器管理工具.它具有Docker原生编排功能,采用轻量化架构,帮助开发者快速搭建DevOps环境, ...

  4. 【JZOJ4882】【NOIP2016提高A组集训第12场11.10】多段线性函数

    题目描述 数据范围 解法 三分找出极值,两个二分找出极值的范围. 代码 #include<iostream> #include<stdio.h> #include<str ...

  5. MUI - 关于百度定位

    关于百度定位 这是官方定位的解释:geolocation 地图插件配置 我在问答里面找到了这位童鞋的百度定位,地址变更提醒 *** 不过,童鞋倒是给具体的示例啊,木有~~~~(>_<)~~ ...

  6. 【NS2】用eclipse调试NS2(转载)

    相信很多喜欢Java的人对eclipse都情有独钟.NS2程序的调试,可以用打印命令调试,这样太繁琐.也可以用gdb调试,个人觉得上手比较困难.相信各位学习NS2的新手,在看代码的时候,很多的函数或者 ...

  7. 修改oracle编码格式

    文章参照:https://www.jb51.net/article/53078.htm 1.查看oracle当前编码格式: SELECT * FROM V$NLS_PARAMETERS WHERE P ...

  8. python 字典元素删减

  9. ROS出现“Couldn't find executable named listener below //home/xxx/catkin_ws/src/mypack”问题

    在执行节点时出现了如下图所示的错误: 错误原因是在路径下找不到可执行的节点文件.但事实是已经对工作空间进行了编译,并且在devel /lib/my_serial_node 中已经生成了可执行文件. 如 ...

  10. 阿里开源!轻量级深度学习端侧推理引擎 MNN

    阿里妹导读:近日,阿里正式开源轻量级深度学习端侧推理引擎“MNN”. AI科学家贾扬清如此评价道:“与 Tensorflow.Caffe2 等同时覆盖训练和推理的通用框架相比,MNN 更注重在推理时的 ...