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. oralce如何修改默认的XDB监听端口

    Oracle9i默认的XML DB把HTTP的默认端口设为8080,这是一个太常用的端口了,很多别的WebServer都会使用这个端口, 如果我们安装了它,最好修改一下,避免冲突,如果不使用呢,就最好 ...

  2. SDUT-3362_村村通公路

    数据结构实验之图论六:村村通公路 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 当前农村公路建设正如火如荼的展开,某乡 ...

  3. SDUT-2121_数据结构实验之链表六:有序链表的建立

    数据结构实验之链表六:有序链表的建立 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入N个无序的整数,建立一个有序链 ...

  4. @loj - 2434@ 「ZJOI2018」历史

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 九条可怜是一个热爱阅读的女孩子. 这段时间,她看了一本非常有趣的 ...

  5. 微信小程序之购物车demo

    这篇小demo主要使用了一下几个技术点 1.全局变量的使用 在这里定义的变量 任何一个页面和组件都可以访问到 在使用到的页面 const app = getApp(); 声明一个实例 然后 app.g ...

  6. Object-c学习笔记十八-----NSPredicate

    Cocoa提供了一个类NSPredicate类,该类主要用于指定过滤器的条件,该对象可以准确的描述所需条件,对每个对象通过谓词进行筛选,判断是否与条件相匹配.谓词表示计算真值或假值的函数. NSPre ...

  7. python基础之逻辑题(2)

    python基础之逻辑题(2) 1.若k为整数,下列while循环执行的次数为? 2.请输出正确结果-----numbers? 3.求结果-----math?   4.求结果-----sum? 5.输 ...

  8. @bzoj - 4382@ [POI2015] Podział naszyjnika

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 长度为 n 的一串项链,每颗珠子是 k 种颜色之一. 第 i 颗 ...

  9. Windows系统下三十款优秀开源软件

    Windows系统下三十款优秀开源软件 1.Firefox 官方网站:http://www.getfirefox.com/ 可替换Internet Explorer 功能特点:如果你还没有使用Fire ...

  10. jq获取单选框、复选框、下拉菜单的值

    1.<input type="radio" name="testradio" value="jquery获取radio的值" /> ...