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. [LeetCode] 876. Middle of the Linked List 链表的中间结点

    Given a non-empty, singly linked list with head node head, return a middle node of linked list. If t ...

  2. [LeetCode] 490. The Maze 迷宫

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  3. Gitea 使用方法

    安装部分笔记 创建专用数据库及用户 create database if not exists gitea default charset = utf8mb4; grant ALL PRIVILEGE ...

  4. OAuth2、OpenID、SMAL 对比

    对比点 OAuth2.0 OpenID SMAL2 票据格式 JSON or SAML2 JSON XML 支持授权 Yes Yes Yes 支持认证 “伪认证” Yes Yes 创建年份 2005 ...

  5. IDCode校验算法

    运行地址: https://c.runoob.com/compile/10 算法源码 public class HelloWorld { public static void main(String ...

  6. 可以获取随机图片的API收集 必应 等

    食用方法可以是img标签嵌入在网页中, 也可以在iwall.app里面设置你的桌面背景.还有其他好用的API吗? 请在下放留下您的评论. 非常感谢! 速度: ★★★★★ 功能: 返回Bing的随机图片 ...

  7. mysql操作(精简版)

    一.数据库操作(建库.删库) 1.查看数据库:show databases; 2.创建数据库:DROP DATABASE 数据库名; 3.删除数据库:CREATE DATABASE 数据库名; 4.使 ...

  8. centos上安装grafana

    wget https://dl.grafana.com/oss/release/grafana-6.2.5-1.x86_64.rpm yum localinstall grafana-6.2.5-1. ...

  9. luogu P2258 子矩阵 |动态规划

    题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第22.44行和第22.44.55列交叉 ...

  10. VUE方法

    1.$event 变量 $event 变量用于访问原生DOM事件. <!DOCTYPE html> <html lang="zh"> <head> ...