2279. I want out of that maze!
单点时限: 2.0 sec
内存限制: 256 MB
Your’re on holiday in Egypt. Of cause you also visit the pyramids. On your way through the dark lodes, you lost your group and now it’s your job to find a way through the dark maze and find the exit…
Sometimes the exit is very well hidden. So no tourist, even you, can find the way out. If this happens, you can only pray and wait for the next tourist-group - perhaps they may find you.
You will get a map of the whole labyrinth. The maze has the maximal dimension of 100 x 100 fields. You have to find a way through the labyrinth or if there is no way out, you have to print “No way out!”.
There is only two condition for your walk: Your’ re not allowed to pass a field twice and - of cause you can’t walk through walls!
输入格式
The first line consists of the dimension of the labyrinth. The first digit stands for the columns and the second describes the number of rows. After this the whole labyrinth will be shown.
1 * stands for a wall - you may not walk through it.
2 . stands for a free way, thats where you can walk
3 Z is your aim, it is the exit of the labyrinth
4 X this is you!
After you’ve passed one labyrinth, another one may follow! The last labyrinth will be recognized by a zero (0) . Every labyrinth may have more than one way out, but of cause it can also have no way out!
输出格式
First you’ve to write the number of the labyrinth you’ re just walking through. And then the way you took by orientation. That means, you have to write n(orth), w(est), s(outh) or e(ast).
Another condition is, that you’ve to find the lexicographical shortest way through the maze! That means that every labyrinth may have only one way out, which is correct…
If you find the following ways out, only the first of them is the correct answer:
eeennnessessws
eeeses
enessessen
sseeee
(lexicographically sorted)
If there was no possible way through the labyrinth, you have to print the line ‘No way out!’ and process the next labyrinth if there is another one.
样例
input
18 5
.Z**.*.....*......
..**.*****.*.***.*
*..*.....*...*....
.*.**.*..*..**X**.
......**....*...*.
2 2
X*
*Z
3 4
***
.X.
...
..Z
0
output
#1: neennwwwwsswsswwwnnwwwsswwwnnwnn
#2: No way out!
#3: ess
心得:
一开始题意理解错了,直接bfs
,然后发现错了,题意要求能到达时要用字典序最小的,不在乎路多长。接着直接改dfs
,然后超时了。感觉超时原因应该是dfs
在找不到出口时花费时间过长,于是先用bfs
确定是否能找到出口(也想过用并查集来确认连通性,但是有已经写好的bfs
直接可以用),然后dfs
找到那条字典序最短的路。
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int directions[4][2]={0,1,-1,0,1,0,0,-1};//e,n,s,w
char directchar[4]={'e','n','s','w'};
bool dfs(vector<string> maze,int x,int y,string s){
int rows=maze.size(),columns=maze[0].size();
bool success=false;
for(int i=0;i<4;i++){
int xi=x+directions[i][0],yi=y+directions[i][1];
if(xi>=0&&xi<rows&&yi>=0&&yi<columns&&maze[xi][yi]!='*'){
s+=directchar[i];
if(maze[xi][yi]=='Z'){
cout<<s<<endl;
return true;
}
maze[xi][yi]='*';
success=dfs(maze,xi,yi,s);
if(success)return success;
maze[xi][yi]='.';
s.pop_back();
}
}
return success;
}
int main(){
int columns,rows,nums=1;
string s;
while(1){
scanf("%d",&columns);
if(columns==0)break;
scanf("%d",&rows);
vector<string> maze(rows),maze1(rows),ans;
int X,Y,cnt=0,canOut=0;
getchar();
for(int i=0;i<rows;i++){
maze[i].resize(columns);
scanf("%s",&maze[i][0]);
maze1[i]=maze[i];
if(cnt==0){
for(int j=0;j<columns;j++){
if(maze[i][j]=='X'){
X=i,Y=j;
cnt++;
}
}
}
}
cout<<"#"<<nums<<": ";
nums++;
queue<pair<int,string>> q;
q.push(make_pair(X*1000+Y,string()));
while(!q.empty()){
pair<int,string> currentNode=q.front();
q.pop();
int x=currentNode.first/1000,y=currentNode.first%1000;
for(int i=0;i<4;i++){
int xi=x+directions[i][0],yi=y+directions[i][1];
if(xi>=0&&xi<rows&&yi>=0&&yi<columns&&maze1[xi][yi]!='*'){
pair<int,string> tmpPair=make_pair(xi*1000+yi,currentNode.second+directchar[i]);
if(maze1[xi][yi]=='Z'){
canOut=1;
q=queue<pair<int,string>>();
break;
}
q.push(tmpPair);
maze1[xi][yi]='*';
}
}
}
if(canOut==0){
cout<<"No way out!"<<endl;
continue;
}
maze[X][Y]='*';//一开始也忘了改起点为‘*’
dfs(maze,X,Y,string());
}
}