sicily 1215. 脱离地牢
在一个神秘的国度里,年轻的王子Paris与美丽的公主Helen在一起过着幸福的生活。他们都随身带有一块带磁性的阴阳魔法石,身居地狱的魔王Satan早就想得到这两块石头了,只要把它们熔化,Satan就能吸收其精华大增自己的魔力。于是有一天他趁二人不留意,把他们带到了自己的地牢,分别困在了不同的地方。然后Satan念起了咒语,准备炼狱,界时二人都将葬身于这地牢里。
危险!Paris与Helen都知道了Satan的意图,他们要怎样才能打败魔王,脱离地牢呢?Paris想起了父王临终前留给他的备忘本,原来他早已料到了Satan的野心,他告诉Paris只要把两块魔法石合在一起,念出咒语,它们便会放出无限的光亮,杀死魔王,脱离地牢,而且本子上还附下了地牢的地图,Paris从中了解到了Helen的位置所在。于是他决定首先要找到Helen,但是他发现这个地牢很奇怪,它会增强二人魔法石所带磁力的大小,而且会改变磁力的方向。这就是说,每当Pairs向南走一步,Helen有可能会被石头吸引向北走一步。而这个地狱布满了岩石与熔浆,Pairs必须十分小心,不仅他不能走到岩石或熔浆上,而且由于他行走一步,Helen的位置也会改变,如果Helen碰到岩石上,那么她将停留在原地,但如果Helen移动到了熔浆上,那么她将死去,Paris就找不到她了。
Pairs仔细分析了地图,他找出了一条最快的行走方案,最终与Helen相聚。他们一起念出了咒语"@^&#……%@%&$",轰隆一声,地牢塌陷了,他们又重见光明……
5 5
#####
#H..#
#.!.#
#.#P#
#####
WNSE
5 解释:Paris行走方案为NNWWS,每步过后Helen位置在(2,2), (2,2), (3,2), (4,2), (3,2)。
分析:因为要找的是最短步数,所以用 bfs,
二人在相邻两格移动后碰在了一起的时候,步数算他们移动后的步数。
注意 H 不能移动的情况
当 H 和 P 两者的状态和前面某一状态相同时,说明循环了,也就是要保存两者的状态,注意这里的状态由 H 和 P 两者的位置决定,而不是由其中某一个决定。
#include <iostream>
#include <map>
#include <queue>
#include <cstring> using namespace std; char pict[][];
bool visited[][][][]; struct Node {
Node(int Px_ = , int Py_ = , int Hx_ = , int Hy_ = , int step_ = ):
Px(Px_), Py(Py_), Hx(Hx_), Hy(Hy_), step(step_) { }
int Px, Py, Hx, Hy;
int step;
}; struct Location {
Location(int x_ = , int y_ = ) : x(x_), y(y_) { }
int x, y;
}; Location P, H;
map<char, Location> directionChange;
char Hd[];
char Pd[] = {'N', 'S', 'W', 'E'}; bool isValid(int x, int y, int n, int m) {
return x >= && y >= && x < n && y < m;
} int solve(int n, int m) {
queue< Node > q;
q.push(Node(P.x, P.y, H.x, H.y, ));
visited[P.x][P.y][H.x][H.y] = true;
while (!q.empty()) {
Node current = q.front();
q.pop();
if (current.step > ) {
return -;
} current.step++;
for (int i = ; i != ; ++i) {
int Px = current.Px + directionChange[Pd[i]].x;
int Py = current.Py + directionChange[Pd[i]].y;
int Hx = current.Hx + directionChange[Hd[i]].x;
int Hy = current.Hy + directionChange[Hd[i]].y; if (pict[Hx][Hy] == '#') {
Hx = current.Hx;
Hy = current.Hy;
} if (isValid(Px, Py, n, m) && isValid(Hx, Hy, n, m)) {
if (pict[Px][Py] == '.' && pict[Hx][Hy] != '!' && !visited[Px][Py][Hx][Hy]) {
if ((Hx == current.Px && Hy == current.Py && Px == current.Hx && Py == current.Hy) ||
(Px == Hx && Py == Hy)) {
return current.step;
}
visited[Px][Py][Hx][Hy] = true;
q.push(Node(Px, Py, Hx, Hy, current.step));
}
}
}
} return -;
} int main(int argc, char const *argv[])
{
int n, m;
while (cin >> n >> m) {
memset(visited, false, sizeof(visited));
for (int i = ; i != n; ++i) {
for (int j = ; j != m; ++j) {
cin >> pict[i][j];
if (pict[i][j] == 'P') {
pict[i][j] = '.';
P.x = i;
P.y = j;
}
if (pict[i][j] == 'H') {
pict[i][j] = '.';
H.x = i;
H.y = j;
}
}
}
for (int i = ; i != ; ++i) {
cin >> Hd[i];
}
directionChange['N'] = Location(-, );
directionChange['S'] = Location(, );
directionChange['W'] = Location(, -);
directionChange['E'] = Location(, );
int step = solve(n, m);
if (step == -)
cout << "Impossible" << endl;
else
cout << step << endl;
}
return ;
}
-----------------------------分割线------------------------------------------
当代码是如下时:
#include <iostream>
#include <map>
#include <queue>
#include <cstring> using namespace std; char pict[][];
bool visited[][][][]; struct Node {
Node(int Px_ = , int Py_ = , int Hx_ = , int Hy_ = , int step_ = ):
Px(Px_), Py(Py_), Hx(Hx_), Hy(Hy_), step(step_) { }
int Px, Py, Hx, Hy;
int step;
}; struct Location {
Location(int x_ = , int y_ = ) : x(x_), y(y_) { }
int x, y;
}; Location P, H;
map<char, Location> directionChange;
char Hd[];
char Pd[] = {'N', 'S', 'W', 'E'}; bool isValid(int x, int y, int n, int m) {
return x >= && y >= && x < n && y < m;
} int solve(int n, int m) {
queue< Node > q;
q.push(Node(P.x, P.y, H.x, H.y, ));
visited[P.x][P.y][H.x][H.y] = true;
while (!q.empty()) {
Node current = q.front();
q.pop();
if (current.step > ) {
return -;
}
if (current.Px == current.Hx && current.Py == current.Hy) {
return current.step;
}
current.step++;
for (int i = ; i != ; ++i) {
int Px = current.Px + directionChange[Pd[i]].x;
int Py = current.Py + directionChange[Pd[i]].y;
int Hx = current.Hx + directionChange[Hd[i]].x;
int Hy = current.Hy + directionChange[Hd[i]].y; if (pict[Hx][Hy] == '#') {
Hx = current.Hx;
Hy = current.Hy;
} if (isValid(Px, Py, n, m) && isValid(Hx, Hy, n, m)) {
if (pict[Px][Py] == '.' && pict[Hx][Hy] != '!' && !visited[Px][Py][Hx][Hy]) {
if (Hx == current.Px && Hy == current.Py && Px == current.Hx && Py == current.Hy) {
return current.step;
}
visited[Px][Py][Hx][Hy] = true;
q.push(Node(Px, Py, Hx, Hy, current.step));
}
}
}
} return -;
} int main(int argc, char const *argv[])
{
int n, m;
while (cin >> n >> m) {
memset(visited, false, sizeof(visited));
for (int i = ; i != n; ++i) {
for (int j = ; j != m; ++j) {
cin >> pict[i][j];
if (pict[i][j] == 'P') {
pict[i][j] = '.';
P.x = i;
P.y = j;
}
if (pict[i][j] == 'H') {
pict[i][j] = '.';
H.x = i;
H.y = j;
}
}
}
for (int i = ; i != ; ++i) {
cin >> Hd[i];
}
directionChange['N'] = Location(-, );
directionChange['S'] = Location(, );
directionChange['W'] = Location(, -);
directionChange['E'] = Location(, );
int step = solve(n, m);
if (step == -)
cout << "Impossible" << endl;
else
cout << step << endl;
}
return ;
}
改了 n 次都是 WA,很奇怪,因为这里和第一份代码的效果应该是一样的,因为是广搜,就算是因为在
if (Hx == current.Px && Hy == current.Py && Px == current.Hx && Py == current.Hy) {
return current.step;
}
这里提前返回了,那也是同一层,那么步数应该是一样的。那么就只有一种情况会出现错误了,如下:

当能达到结果的树形状如上的时候,1 是要在遍历下一层节点的时候才会发现它是不是达到目标状态的,这个时候,2反而先被发现,但 2 并不是最短的,所以此时会出错。
sicily 1215. 脱离地牢的更多相关文章
- Sicily 1215: 脱离地牢(BFS)
这道题按照题意直接BFS即可,主要要注意题意中的相遇是指两种情况:一种是同时到达同一格子,另一种是在移动时相遇,如Paris在(1,2),而Helen在(1,2),若下一步Paris到达(1,1),而 ...
- 20180610模拟赛T1——脱离地牢
Description 在一个神秘的国度里,年轻的王子Paris与美丽的公主Helen在一起过着幸福的生活.他们都随身带有一块带磁性的阴阳魔法石,身居地狱的魔王Satan早就想着得到这两块石头了,只要 ...
- sicily 题目分类
为了方便刷题,直接把分类保存下来方便来找. 转自:http://dengbaoleng.iteye.com/blog/1505083 [数据结构/图论] 1310Right-HeavyTree笛卡尔树 ...
- POJ 2251 Dungeon Master(地牢大师)
p.MsoNormal { margin-bottom: 10.0000pt; font-family: Tahoma; font-size: 11.0000pt } h1 { margin-top: ...
- dynamic-css 动态 CSS 库,使得你可以借助 MVVM 模式动态生成和更新 css,从 js 事件和 css 选择器的苦海中脱离出来
dynamic-css 使得你可以借助 MVVM 模式动态生成和更新 css,从而将本插件到来之前,打散.嵌套在 js 中的修改样式的代码剥离出来.比如你要做元素跟随鼠标移动,或者根据滚动条位置的变化 ...
- 从EF的使用中探讨业务模型能否脱离单一存储层完全抽象存在
上次赶时间,就很流水账地写了上次项目对EF的一次实践应用模式,因为太长了,也没能探讨太多,所以再继续扩展. 这次想探讨的是,实体,如果作为类似于领域模型的业务模型存在,它的数据能否来自不同的数据源.这 ...
- 【H5疑难杂症】脱离文档流时的渲染BUG
BUG重现 最近机票团队在一个页面布局复杂的地方发现一个BUG,非常奇怪并且不好定位,这类问题一般最后都会到我这里,这个问题是,改变dom结构,页面却不渲染!!! 如图所示,我动态的改变了dom结构, ...
- 让T4脱离VS生成代码
让T4脱离VS生成代码 最近项目快结束:空闲时间相对多一点:为了以后工作方便点:索性研究了VS的T4: 写个代码生成器:以后可以通过代码生成器调用项目里面的Dll直接生成代码或者xml: 应用以下两个 ...
- sicily 中缀表达式转后缀表达式
题目描述 将中缀表达式(infix expression)转换为后缀表达式(postfix expression).假设中缀表达式中的操作数均以单个英文字母表示,且其中只包含左括号'(',右括号‘)’ ...
随机推荐
- 【BZOJ2463】谁能赢呢?(博弈论)
[BZOJ2463]谁能赢呢?(博弈论) 题面 BZOJ 洛谷 题解 洛谷上对于难度的评级我总觉有些问题. 很多人按照代码难度而并非思维难度在评级,导致很多评级很不合理啊... 不说废话了.. 对于一 ...
- Error while uploading slice_4.apk : WARNING: linker: libhoudini.so has text relocations. This is wasting memory and prevents security hardening. Please fix.
问题: android studio 2.4版本新建项目后老是编译不过,查看log报如下错误,最后发现关闭即时编译功能可以解决此问题.这也算是2.4测试版的bug吧 android - Error w ...
- bzoj 1856: [Scoi2010]字符串 卡特兰数
1856: [Scoi2010]字符串 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1458 Solved: 814[Submit][Status][ ...
- 【最小割/二分图最大独立集】【网络流24题】【P2774】 方格取数问题
Description 给定一个 \(n~\times~m\) 的矩阵,每个位置有一个正整数,选择一些互不相邻的数,最大化权值和 Limitation \(1~\leq~n,~m~\leq~100\) ...
- SQL联合查询中的关键语法
http://www.cnblogs.com/aaapeng/archive/2010/01/20/1652151.html 联合查询效率较高.以下例子来说明联合查询的好处 t1表结构(用户名,密码) ...
- git<撤销本地修改与回退版本>
1. 使用 git checkout 撤销本地修改 即放弃对本地已修改但尚未提交的文件的修改,还原其到未修改前的状态. 注意: 已 add/ commit 的文件不适用个方法,应该用本文提到的第二种方 ...
- 用R做时间序列分析之ARIMA模型预测
昨天刚刚把导入数据弄好,今天迫不及待试试怎么做预测,网上找的帖子跟着弄的. 第一步.对原始数据进行分析 一.ARIMA预测时间序列 指数平滑法对于预测来说是非常有帮助的,而且它对时间序列上面连续的值之 ...
- [python]python安装包错误
“UnicodeDecodeError: ‘ascii’ codec can’t decode : ordinal not )” 在windows XP上 解决方法: Solution: ====== ...
- aapt命令说明
这里借用一下百度百科,我比较懒 1.列出apk包的内容 aapt l[ist] [-v] [-a] <你的应用> -v 以table形式列出来 -a 详细列出内容 例如:aapt l &l ...
- python pop()
pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值. obj -- 可选参数,要移除列表元素的索引值,不能超过列表总长度,默认为 index=-1,删除最后一个列表值 l ...