Description

在一个神秘的国度里,年轻的王子Paris与美丽的公主Helen在一起过着幸福的生活。他们都随身带有一块带磁性的阴阳魔法石,身居地狱的魔王Satan早就想着得到这两块石头了,只要把它们溶化,Satan就能吸收其精华大增自己的魔力。于是有一天他趁二人不留意,把他们带到了自己的地牢,分别困在了不同的地方。然后Satan念起了咒语,准备炼狱,界时二人都将葬身于这地牢里。 危险!Paris与Helen都知道了Satan的意图,他们要怎样才能打败魔王,脱离地牢呢?Paris想起了父王临终前给他的备忘本,原来他早已料到了Satan的野心,他告诉Paris只要把两块魔法石合在一起,念出咒语,它们便会放出无限的光荣,杀死魔王,脱离地牢,而且本子上还附下了地牢的地图,Paris从中了解到了Helen的位置所在。于是他决定首先要找到Helen,但是他发现这个地牢很奇怪,它会增强二人魔法石所带的磁力大小,而且会改变磁力的方向。这就是说,每当Paris向南走一步,Helen有可能会被石头吸引向北走一步。而这个地狱布满了岩石与熔浆,Paris必须十分小心,不仅他不能走到岩石或熔浆上,而且由于他行走一步,Helen的位置也会改变,如果Helen碰到岩石上,那么她将停留在原地,但如果Helen移动到了熔浆上,那么她将死去,Paris就找不到她了。 Paris仔细分析了地图,他找出了一条最快的行走方案,最终与Helen相聚。他们一起念出了咒语“·#¥%^…*&@!”,轰隆一声,地牢塌陷了,他们又重见光明…

Input

输入数据第一行为两个整数n,m(3<=n,m<=20),表示地牢的大小,n行m列。接下来n行,每行m个字符,描述了cf地牢的地图,“.”代表通路,“#”代表岩石,“!”代表熔浆,“H”表示Helen,“P”表示Paris。输入保证地牢是封闭的,即四周均是岩石或熔浆。接下来一行有四个字符“N”(北),“S”(南),“W”(西),“E”(东)的排列,表示Paris分别向NSWE四个方向走时Helen受磁石磁力影响的移动方向。

Output

输出文件只有一行,如果Paris能找到Helen,输出一整数d,为Paris最少需要行走的步数;如果Paris在255步之后仍找不到Helen,则输出“Impossible”。注意相遇是指Paris与Helen最终到达同一个格子,或者二人在相邻两格移动后碰到了一起,而后者的步数算他们移动后的步数。

Sample Input

5 5

#####

#H..#

#.!.#

#.#P#

#####

WNSE

Sample Output

5

题解

话说这几天每次模拟赛怎么都有一道搜索……

裸的bfs。然而交上去只有奇怪的80分,发现是没注意这句话:

注意相遇是指Paris与Helen最终到达同一个格子,或者二人在相邻两格移动后碰到了一起,而后者的步数算他们移动后的步数。

就是如果Paris从A到B,Helen从B到A,那么也算碰到了一起。

于是这个需要判一下。

感觉没什么好讲的了,就直接上代码吧。

#include <cstdio>
#include <queue> using namespace std; const int maxn = 25; int n, m; char mmap[maxn][maxn];
bool vis[maxn][maxn][maxn][maxn];//直接记录状态 struct sxd//这是机房大佬,请不要在意
{
int hi, hj, pi, pj;
int bs;
}; const int diri[] = {-1, 1, 0, 0};
const int dirj[] = {0, 0, -1, 1};
int dirhi[5];
int dirhj[5]; int main()
{
freopen("escape.in", "r", stdin);
freopen("escape.out", "w", stdout);
scanf("%d%d\n", &n, &m);
sxd first;
first.bs = 0;
for(int i = 0; i < n; ++i)
{
gets(mmap[i]);
for(int j = 0; j < m; ++j)
{
if(mmap[i][j] == 'H')
{
first.hi = i;
first.hj = j;
mmap[i][j] = '.';
}
else if(mmap[i][j] == 'P')
{
first.pi = i;
first.pj = j;
mmap[i][j] = '.';
}
}
}
queue<sxd> Q;
Q.push(first);
vis[first.pi][first.pj][first.hi][first.hj] = true;
char tmp[5];
gets(tmp);
for(int i = 0; i < 4; ++i)
{
switch(tmp[i])
{
case 'W':
dirhi[i] = 0;
dirhj[i] = -1;
break;
case 'N':
dirhi[i] = -1;
dirhj[i] = 0;
break;
case 'S':
dirhi[i] = 1;
dirhj[i] = 0;
break;
case 'E':
dirhi[i] = 0;
dirhj[i] = 1;
break;
}
}
while(!Q.empty())
{
sxd now = Q.front();
Q.pop();
if(now.bs > 255)
break;
for(int i = 0; i < 4; ++i)
{
sxd nxt = now;
nxt.bs++;
nxt.pi += diri[i];
nxt.pj += dirj[i];
nxt.hi += dirhi[i];
nxt.hj += dirhj[i];
if(nxt.hi == now.pi && nxt.hj == now.pj && nxt.hj == now.pj && now.hi == nxt.pi)//注意判交错情况
{
printf("%d", nxt.bs);
fclose(stdin);
fclose(stdout);
return 0;
}
if(mmap[nxt.pi][nxt.pj] != '.' || mmap[nxt.hi][nxt.hj] == '!')
continue;
if(mmap[nxt.hi][nxt.hj] == '#')//注意Helen是可以撞墙的。
{
nxt.hi = now.hi;
nxt.hj = now.hj;
}
if(nxt.hi == nxt.pi && nxt.hj == nxt.pj)
{
printf("%d", nxt.bs);
fclose(stdin);
fclose(stdout);
return 0;
}
if(!vis[nxt.pi][nxt.pj][nxt.hi][nxt.hj])
{
Q.push(nxt);
vis[nxt.pi][nxt.pj][nxt.hi][nxt.hj] = true;
}
}
}
puts("Impossible");
fclose(stdin);
fclose(stdout);
return 0;
}

20180610模拟赛T1——脱离地牢的更多相关文章

  1. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  2. NOIP欢乐模拟赛 T1 解题报告

    小澳的方阵 (matrix.cpp/c/pas) [题目描述] 小澳最近迷上了考古,他发现秦始皇的兵马俑布局十分有特点,热爱钻研的小澳打算在电脑上还原这个伟大的布局. 他努力钻研,发现秦始皇布置兵马俑 ...

  3. [模拟赛] T1 高级打字机

    Description 早苗入手了最新的高级打字机.最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧. 请为这种高级打字机设计一个程序,支持如下3种操作: 1.T x:在文章末尾打下一个小 ...

  4. 2019.2.25 模拟赛T1【集训队作业2018】小Z的礼物

    T1: [集训队作业2018]小Z的礼物 我们发现我们要求的是覆盖所有集合里的元素的期望时间. 设\(t_{i,j}\)表示第一次覆盖第i行第j列的格子的时间,我们要求的是\(max\{ALL\}\) ...

  5. [NOIP2018校模拟赛]T1 阶乘

    题目: 描述 有n个正整数a[i],设它们乘积为p,你可以给p乘上一个正整数q,使p*q刚好为正整数m的阶乘,求m的最小值. 输入 共两行. 第一行一个正整数n. 第二行n个正整数a[i]. 输出 共 ...

  6. [NOIP2018校模拟赛]T1聚会 party

    题目链接: 聚会 分析: 设每个点到1号点的距离为dist_{i},每个点的权值为x_{i},目标点到1号点的距离为dist,权值为x,那么对于每一次查询,我们讨论三种情况: ① 目标家庭在区间左边( ...

  7. 【2019.8.15 慈溪模拟赛 T1】插头(plugin)(二分+贪心)

    二分 首先,可以发现,最后的答案显然满足可二分性,因此我们可以二分答案. 然后,我们只要贪心,就可以验证了. 贪心 不难发现,肯定会优先选择能提供更多插座的排插,且在确定充电器个数的情况下,肯定选择能 ...

  8. 【2019.7.20 NOIP模拟赛 T1】A(A)(暴搜)

    打表+暴搜 这道题目,显然是需要打表的,不过打表的方式可以有很多. 我是打了两个表,分别表示每个数字所需的火柴棒根数以及从一个数字到另一个数字,除了需要去除或加入的火柴棒外,至少需要几根火柴棒. 然后 ...

  9. 【2019.7.25 NOIP模拟赛 T1】变换(change)(思维+大分类讨论)

    几个性质 我们通过推式子可以发现: \[B⇒AC⇒AAB⇒AAAC⇒C\] \[C⇒AB⇒AAC⇒AAAB⇒B\] 也就是说: 性质一: \(B,C\)可以相互转换. 则我们再次推式子可以发现: \[ ...

随机推荐

  1. Ubuntu16LTS使用笔记(Server版)

    环境测试:Ubuntu Server 16.04.06 x64 虚拟机 以下均需要root权限,请sudo 或 su root 解决只有先启动Windows再重启到Linux才能使用usb网卡的问题: ...

  2. JavaWeb 笔记

    WEB-INF 目录 web.xml 文件配置 精准匹配 "/" "/index" "/go/index.html" 路径通配匹配 &quo ...

  3. hbase 查看元数据

    package com.jason.lala.pipe.dbinfo import com.jason.lala.common.query.option.HbaseOptions import org ...

  4. torch_09_DCGAN_注意的细节

    DCGAN github链接:https://github.com/darr/DCGAN DCGAN:1.在一次epoch中,如果第i批的i能够整除every_print,则打印到output文件中( ...

  5. Gitlab安装、备份与恢复

    背景:由于需要把gitlab从A服务器转移到B服务器,故在B服务器进行gitlab的安装和恢复备份 步骤: 一.在B服务器安装Gitlab 1. 获取安装包 wget https://mirrors. ...

  6. 【java】Java多线程总结之线程安全队列Queue【转载】

    原文地址:https://www.cnblogs.com/java-jun-world2099/articles/10165949.html ============================= ...

  7. C# vb .NET读取识别条形码线性条码UPC-A

    UPC-A是比较常见的条形码编码规则类型的一种.如何在C#,vb等.NET平台语言里实现快速准确读取该类型条形码呢?答案是使用SharpBarcode! SharpBarcode是C#快速高效.准确的 ...

  8. 我是如何一步步编码完成万仓网ERP系统的(二)前端框架

    https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...

  9. Delphi - Logs记录,函数实现MsgDsp

    Logs记录-函数实现MsgDsp 大多数时候,我们不太希望消息以交互的形式出现,这个时候我们可以在窗体上放置一个Memo,然后单独开一个线程进行监视,从而实现把消息实时的显示出来,便于开发者分析. ...

  10. Python 查看模块的帮助文档,方法和帮助信息

    参考链接:https://blog.csdn.net/u013810296/article/details/55509284 这里介绍下python自带的查看帮助功能,可以在编程时不中断地迅速找到所需 ...