【25.93%】【676D】Theseus and labyrinth
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的更多相关文章
- 剑指Offer:合并两个排序的链表【25】
剑指Offer:合并两个排序的链表[25] 题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 题目分析 每次都是比较箭头节点,把小节点连接到已经合 ...
- JAVA 基础编程练习题25 【程序 25 求回文数】
25 [程序 25 求回文数] 题目:一个 5 位数,判断它是不是回文数.即 12321 是回文数,个位与万位相同,十位与千位相同. package cskaoyan; public class cs ...
- UI设计师零基础入门到精通精品视频教程【155课高清完整版】
[福吧资源网分享]课程是非常完整的,也是非常零基础的,适合任何学员,有需要的可以下载看看!课程目录:第1章 Adobe Photoshop CS6课时1 Adobe Photoshop CS6入门基础 ...
- 【Android】【录音】Android录音--AudioRecord、MediaRecorder
[Android][录音]Android录音--AudioRecord.MediaRecorder Android提供了两个API用于实现录音功能:android.media.AudioRecord. ...
- 【Xamarin开发 Android 系列 3】循序渐进的学习顺序
原文:[Xamarin开发 Android 系列 3]循序渐进的学习顺序 指定合理的学习步骤,将各个技术点进行强化.慢慢 的就从点到线 到面的飞跃,一切仅仅是时间问题,开始前,请记住,学习是最佳的投资 ...
- 【iScroll源码学习01】准备阶段 - 叶小钗
[iScroll源码学习01]准备阶段 - 叶小钗 时间 2013-12-29 18:41:00 博客园-原创精华区 原文 http://www.cnblogs.com/yexiaochai/p/3 ...
- 【WC2001】【cogs358】高性能计算机(动态规划)
[WC2001][cogs358]高性能计算机(动态规划) ##题面 [问题描述] 现在有一项时间紧迫的工程计算任务要交给你--国家高性能并行计算机的主管工程师--来完成.为了尽可能充分发挥并行计算机 ...
- 【Python】【容器 | 迭代对象 | 迭代器 | 生成器 | 生成器表达式 | 协程 | 期物 | 任务】
Python 的 asyncio 类似于 C++ 的 Boost.Asio. 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知. Asyn ...
- 【Python】【IO】
# [[IO]] # [文件读写] '''读写文件是最常见的IO操作.Python内置了读写文件的函数,用法和C是兼容的.读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现 ...
随机推荐
- PHPCMS快速建站系列之类别调用及类别显示页面
在需要调用类别的地方,比如列表页,首先写循环前面写上一句: <?php $TYPE = getcache('type_content','commons');?> 这句就是把类别缓存加载进 ...
- SAS信用评分之番外篇异常值的识别
SAS信用评分之番外篇异常值的识别 今天想分享给大家的是我早期建模的时候一个识别异常值的办法,也许你在"信用风险评分卡研究"看过,但是代码只能识别一个变量,我将这个代码作了改良,但 ...
- zabbix3.4.x添加短信报警
一.修改zabbix_server.conf #vi /etc/zabbix/zabbix_server.conf 去掉注释: ### Option: AlertScriptsPath # Full ...
- 【转】Sprague-Grundy函数
http://www.cnitblog.com/weiweibbs/articles/42735.html 上一期的文章里我们仔细研究了Nim游戏,并且了解了找出必胜策略的方法.但如果把Nim的规则略 ...
- HZOJ 巨神兵
60pts: 每个DAG的拓扑序是唯一的,所以考虑将DAG分层.f[i][j]记录当前选择的节点状态是i,最后一层的节点状态为j(dep取最大). 初始状态:$f[i][i]=1;i\in [1,1& ...
- Request中getContextPath、getServletPath、getRequestURI、request.getRealPath的区别
1 区别 假定你的web application 名称为news,你在浏览器中输入请求路径: http://localhost:8080/news/main/list.jsp 1.1 System.o ...
- QT 获取系统时间
1.导入QTime #include <QTime> 2.定义QTime 对象接受当前时间 QTime t=QTime::currentTime(); t就是系统时间. 3.将t转化为st ...
- Flask——向博客文章中添加图片
未添加图片样式 添加图片设置: 1.允许渲染img标签 在数据库文章模型allowed_tags中添加img 2.给clean函数加个参数attributes=attrs, attrs = { '*' ...
- jQuery对html元素的取值与赋值实例详解
jQuery对html元素的取值与赋值实例详解 转载 2015-12-18 作者:欢欢 我要评论 这篇文章主要介绍了jQuery对html元素的取值与赋值,较为详细的分析了jQuery针对常 ...
- Open Source Projects Released By Google
Open Source Projects Released By Google Google has released over 20 million lines of code and over 9 ...