【sicily】 1215. 脱离地牢 (重温经典,盗用某某人的一句话:搜索永远是那么得迷人。。。。)
Description
在一个神秘的国度里,年轻的王子Paris与美丽的公主Helen在一起过着幸福的生活。他们都随身带有一块带磁性的阴阳魔法石,身居地狱的魔王Satan早就想得到这两块石头了,只要把它们熔化,Satan就能吸收其精华大增自己的魔力。于是有一天他趁二人不留意,把他们带到了自己的地牢,分别困在了不同的地方。然后Satan念起了咒语,准备炼狱,界时二人都将葬身于这地牢里。 危险!Paris与Helen都知道了Satan的意图,他们要怎样才能打败魔王,脱离地牢呢?Paris想起了父王临终前留给他的备忘本,原来他早已料到了Satan的野心,他告诉Paris只要把两块魔法石合在一起,念出咒语,它们便会放出无限的光亮,杀死魔王,脱离地牢,而且本子上还附下了地牢的地图,Paris从中了解到了Helen的位置所在。于是他决定首先要找到Helen,但是他发现这个地牢很奇怪,它会增强二人魔法石所带磁力的大小,而且会改变磁力的方向。这就是说,每当Pairs向南走一步,Helen有可能会被石头吸引向北走一步。而这个地狱布满了岩石与熔浆,Pairs必须十分小心,不仅他不能走到岩石或熔浆上,而且由于他行走一步,Helen的位置也会改变,如果Helen碰到岩石上,那么她将停留在原地,但如果Helen移动到了熔浆上,那么她将死去,Paris就找不到她了。 Pairs仔细分析了地图,他找出了一条最快的行走方案,最终与Helen相聚。他们一起念出了咒语"@^&#……%@%&$",轰隆一声,地牢塌陷了,他们又重见光明…… Input
输入数据第一行为两个整数n,m(3<=n,m<=20),表示地牢的大小,n行m列。接下来n行,每行m个字符,描述了地牢的地图,"."代表通路,"#"代表岩石,"!"代表熔浆。输入保证地牢是封闭的,即四周均是均是岩石或熔浆。接下来一行有四个字符"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 解释:Paris行走方案为NNWWS,每步过后Helen位置在(2,2), (2,2), (3,2), (4,2), (3,2)。 |
值得注意的是要用一个四维数组来存储每一步后的状态:
1 // source code of submission 581748, Zhongshan University Online Judge System
2 #include <iostream>
3 #include <queue>
4 using namespace std;
5 #include <stdio.h>
6 #include <cstring>
7
8 struct Node{
9 int row,col,hrow,hcol,steps;
10 }node,temp;
11 const int N = 19;
12 char mat[N][N];
13 int visited[N][N][N][N] ,direction[4];
14 queue<Node> q;
15 int row_move[4] = {-1,1,0,0}, col_move[4] = {0,0,-1,1};
16
17 void bfs(){
18 while (!q.empty()){
19 temp = q.front(); q.pop();
20
21 if (temp.steps>255) break;
22
23 for (int i=0;i<4;++i){
24 node.row = temp.row + row_move[i];
25 node.col = temp.col + col_move[i];
26
27 node.hrow = temp.hrow + row_move[direction[i]];
28 node.hcol = temp.hcol + col_move[direction[i]];
29 node.steps = temp.steps + 1;
30
31 if (mat[node.hrow][node.hcol] == '#'){
32 node.hrow = temp.hrow;
33 node.hcol = temp.hcol;
34 }
35 if (mat[node.row][node.col] == '.' && mat[node.hrow][node.hcol] != '!' && !visited[node.row][node.col][node.hrow][node.hcol]){
36 if (node.row == node.hrow && node.col == node.hcol || node.row == temp.hrow && node.col == temp.hcol && node.hrow == temp.row && node.hcol == temp.col){
37 printf("%d\n",node.steps); return ;
38 }
39 visited[node.row][node.col][node.hrow][node.hcol] = 1;
40 q.push(node);
41 }
42 }
43 }
44 printf("Impossible\n");
45 }
46 int main(){
47 //freopen("test.txt","r",stdin);
48 int m,n;
49 while (cin>>n>>m){
50 memset(visited,0,sizeof(visited));
51 for (int i=0;i<n;++i){
52 for (int j=0;j<m;++j){
53 cin>>mat[i][j];
54 if (mat[i][j] == 'P'){
55 node.row = i; node.col = j; mat[i][j] = '.';
56
57 }
58 if (mat[i][j] == 'H'){
59 node.hrow = i; node.hcol = j; mat[i][j] = '.';
60 }
61 }
62 }
63 node.steps = 0;
64 q.push(node);
65
66 char ch;
67 for (int i=0;i<4;++i){
68 cin>>ch;
69 switch(ch){
70 case 'N':
71 direction[i] = 0; break;
72 case 'S':
73 direction[i] = 1; break;
74 case 'W':
75 direction[i] = 2; break;
76 case 'E':
77 direction[i] = 3; break;
78 }
79 }
80 bfs();
81 while (!q.empty()) q.pop();
82 }
83 return 0;
84 }