21. 吃货续

上次郭老师让大家帮忙找餐厅,今天他又来请大家帮忙了。郭老师想从自己的当前位置用最快的时间到达某一餐厅,他每次只能按照上、下、左、右四个方向移动,每次移动计为 1 个时间,但由于路况纷繁复杂,中间有很多的路障,导致他不得不绕过这些路障。此时,具有魔性的高老师出现了,他帮助郭老师在途中的某些点放置了穿梭机,任意两个穿梭机之间可以完成瞬间移动(瞬间移动不耗费时间)。

输入

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

接下来包含 n 行,每行 m 个字符,表示现在的地图。'.' 表示空地,'M' 表示路障,'E' 表示穿梭机,'N' 表示郭老师当前所在的位置,'C' 表示要找的餐厅。'N' 和 'C' 在地图中出现且仅出现一次。

输出

郭老师最快多长时间能到达餐厅。如果永远到不了,输出 "Not Happy"。

测试输入关于“测试输入”的帮助期待的输出关于“期待的输出”的帮助时间限制关于“时间限制”的帮助内存限制关于“内存限制”的帮助额外进程关于“{$a} 个额外进程”的帮助
测试用例 1以文本方式显示
  1. 6 6↵
  2. ...E..↵
  3. EMM.M.↵
  4. .M..M.↵
  5. .MC.M.↵
  6. .MMM..↵
  7. N..E..↵
以文本方式显示
  1. 7↵
1秒1024KB0



#include<stdio.h>//AC
#include<string.h>

char map[2005][2005] = { '\0' };
char vis[2005][2005] = { '\0' };//0-没走过;1-走过
int trend[4][2] = { { 1,0 },{ -1,0 },{ 0,1 },{ 0,-1 } };
int n, m, num=0;

struct CoordinateMode//坐标模式
{
	short mx;
	short my;
	int step;
}Pass[2000000],Queue[4000000];//注意数组大小,有次queue的开2000000结果显示一个WA一个RE

struct CoordinateMode *head, *end;
struct CoordinateMode start;//记录N的位置
int Judge(struct CoordinateMode xx)//边界及限制判断
{
	if (xx.my >= 1 && xx.my <= m && xx.mx >= 1 && xx.mx <= n && map[xx.mx][xx.my] != 'M' && vis[xx.mx][xx.my] != '1')
		return 1;
	else
		return 0;
}

void Q_in(struct CoordinateMode ww)//添加队列
{
	end++;
	*end = ww;
	vis[ww.mx][ww.my] = '1';
}

int Q_empty()//队列是否为空
{
	if (head == end)
		return 1;
	else
		return 0;
}

void Find()
{
	memset(vis, '\0', sizeof(vis));
	head = Queue;
	end = Queue;
	struct CoordinateMode now, next;
	Q_in(start);
	while (!Q_empty())
	{
		head++;
		now = *head;
		for (int i = 0; i<4; i++)
		{
			next.mx = trend[i][0] + now.mx;
			next.my = trend[i][1] + now.my;
			if (Judge(next))
			{
				next.step = now.step + 1;
				if (map[next.mx][next.my] == 'C')
				{
					printf("%d\n", next.step);
					return;
				}

				if (map[next.mx][next.my] == 'E')
				{
					for (int j = 0; j<num; j++)
					{
						Pass[j].step = next.step;
						Q_in(Pass[j]);
					}
				}
				else
					Q_in(next);
			}
		}
	}
	printf("Not Happy\n");
}
int main()
{
	char ch;
	scanf("%d%d", &n, &m);
	getchar();
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
		{
			ch = getchar();
			map[i][j] = ch;
			if (map[i][j] == 'N')
			{
				start.mx = i;
				start.my = j;
				start.step = 0;
			}

			if (map[i][j] == 'E')
			{
				Pass[num].mx = i;
				Pass[num].my = j;
				num++;
			}
		}
		getchar();
	}
	Find();

	return 0;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值