2279. I want out of that maze!

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());
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用C语言解决该问题的代码实现: ```c #include <stdio.h> #include <string.h> #define MAX_N 6 #define MAX_M 6 char maze[MAX_N][MAX_M]; int visited[MAX_N][MAX_M]; int start_x, start_y, end_x, end_y; int num_of_ways = 0; void dfs(int x, int y) { if (x == end_x && y == end_y) { // 到达终点,记录一种方案 num_of_ways++; return; } visited[x][y] = 1; if (x - 1 >= 0 && maze[x-1][y] == 'T' && visited[x-1][y] == 0) { // 向上移动 dfs(x-1, y); } if (x + 1 < MAX_N && maze[x+1][y] == 'T' && visited[x+1][y] == 0) { // 向下移动 dfs(x+1, y); } if (y - 1 >= 0 && maze[x][y-1] == 'T' && visited[x][y-1] == 0) { // 向左移动 dfs(x, y-1); } if (y + 1 < MAX_M && maze[x][y+1] == 'T' && visited[x][y+1] == 0) { // 向右移动 dfs(x, y+1); } visited[x][y] = 0; // 回溯 } int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { scanf("%s", maze[i]); for (int j = 0; j < m; j++) { if (maze[i][j] == 'B') { // 记录起点位置 start_x = i; start_y = j; } else if (maze[i][j] == 'E') { // 记录终点位置 end_x = i; end_y = j; } } } dfs(start_x, start_y); printf("%d\n", num_of_ways); return 0; } ``` 该代码使用深度优先搜索算法来解决问题。具体地,从起点开始,依次向四个方向进行探索,如果可以移动到相邻格子,就继续往前搜索。同时,为了避免重复经过起点和终点,我们需要记录哪些格子已经被访问过,每次回溯时需要将其重置。最终,我们统计可以到达终点的方案数即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值