BIT2014级软件学院程序设计-17 迷宫

这是一道经典的迷宫问题。

迷宫中有起点、终点、空地(可走)、障碍物(不可走)以及若干传送点。

从起点开始,到终点结束,每一时刻只能向上、下、左、右四个方向走一步,走一步消耗一单位时间;任意两个传送点之间可以互相传送,且不消耗时间。

你的目标是计算出从起点走到终点的最短时间。

输入:

第一行包含两个数字n,m(1<=n,m<=2000)

接下来包含n行,每行m个字符,表示现在的地图。'.'表示空地,'M’表示障碍物,’E’表示传送点,'N'表示起点,'C'表示终点。'N'和’C'在地图中出现且仅出现一次。

输出:

一个数字,表示从起点走到终点的最短时间。如果永远走不到,输出“No Way”。

Sample Input

6 6

...E..

EMM.M.

.M..M.

.MC.M.

.MMM..

N..E..

Sample Output

7

 我用的BFS,传送点的话,就第一次碰到传送点就把传送点都入队,当然也可以碰到就入下一个传送点,一个一个入队,反正结果肯定是要都入队,而且每个传送点只入队一次。然后传送点就和这道题没啥关系了。


#include<stdio.h>
#include<string.h>
#define maxn 50000
int n, m,k;//k是多少个传送点
int dx[4] = { 0,0,-1,1 };
int dy[4] = { -1,1,0,0 };
int st[2], ed[2];//起点终点坐标
char map[3000][3000];
int vis[3000][3000];
typedef struct {
	int x, y, step;
}NODE;
int chuan[4000000][2];//传送点的坐标
NODE queue[maxn];
int first, end;//用来记录队列的队首队尾位置


int check(int x, int y)
{
	if (x >= n || x < 0 || y >= m || y < 0||map[x][y]=='M')
		return 0;
	if (vis[x][y])
		return 0;
	return 1;
}
int BFS(int x, int y)
{
	int i,j;
	first = 0;
	end = 0;
	NODE now, next;
	now.x = x;
	now.y = y;
	now.step = 0;
	vis[now.x][now.y] = 1;
	queue[end++] = now;
	j=0;
	while (first != end)
	{

		now = queue[first];
		if (now.x == ed[0] && now.y == ed[1])
		{
			return now.step;
		}
		first++;//q.pop()
		if (first >= maxn)//
			first = 0;//
		if (map[now.x][now.y] == 'E'&&j<k)
		{
			
				next.x = chuan[j][0];next.y = chuan[j][1];next.step = now.step ;
				if (check(next.x, next.y))
				{
					vis[next.x][next.y] = 1;
					queue[end++] = next;//q.push()
					if (end >= maxn)//
						end = 0;
				}
				j++;

		}


		for (i = 0;i <=3;i++)
		{
			next.x = now.x + dx[i];
			next.y = now.y + dy[i];
			next.step = now.step + 1;
			if (check(next.x, next.y))
			{
				vis[next.x][next.y] = 1;
				queue[end++] = next;//q.push
				if (end >= maxn)//
					end = 0;//
			}
		}


	}
	return -1;
}


int main()
{
	int ans;
	int i,j;
	scanf("%d%d", &n, &m);

	for (i = 0;i < n;i++)
		scanf("%s", &map[i]);
	k = 0;
	for (i = 0;i < n;i++)
		for (j = 0;j < m;j++)
		{
			vis[i][j]=0;
			if (map[i][j] == 'N')
			{
				st[0] = i;st[1] = j;
			}
			if (map[i][j] == 'C')
			{
				ed[0] = i;ed[1] = j;
			}
			if (map[i][j] == 'E')
			{
				chuan[k][0] = i;chuan[k][1] = j;
				k++;
			}
		}

	ans = BFS(st[0],st[1]);
	if (ans == -1)
		printf("No Way\n");
	else printf("%d\n", ans);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值