帅气的HYC迷路了(带方向)

本文介绍了一个迷宫寻宝问题的解决方案,包括按照特定规则行走寻找出口的算法实现及寻找最短路径的方法。通过深度优先搜索(DFS)确定按照规则行走的步数,利用广度优先搜索(BFS)找出最短路径。

 有一天, 我们帅气的HYC找到了一张藏宝图, 这张图很神奇, 只要你看它一眼, 立马就会被传送到一个迷宫里, 这个迷宫仅有一个出口.那么现在问题来啦, 问你找到这个出口需要走多少步?

    现在给出HYC在迷宫房中走的规则, HYC每走出一步, 都会优先向左走, 如果左边是墙, 那么他会向前走, 如果前边也是墙, 那么他就会向右走, 如果右边也是墙, 那么他只能选择后退了~~~~>_<~~~~

    另外, HYC也想知道如果不这样走, 他最少能走多少步能走出出口呢?

首先给出一个T (1 <= T < 100) 代表T组测试数据
每组测试数据第一行为两个整数r 和 c (3 <= r,c <= 40) r代表这个迷宫有多少列,c代表这个迷宫有多少行.
S表示入口, E表示出口, #表示墙不能走, .表示空白区域, 可以走.
题目保证给出的迷宫四周都是墙, 而且按照规则走总能找到出口, 且初始方向为向北走,快来帮帮他吧!

每组数据输出两个数, 第一个数表示按照规则走的步数, 第二个数表示走到出口最短需要多少步.

 复制
1
9 5
#########
#.#.#.#.#
S.......E
#.#.#.#.#
#########
17 9、
问题分析:这里因为他说是按了方向前进的,所以way数组的元素值顺序是确定的,所以在求第一个步数的时候要有一个方向参数dir,并且找到dir和方向数组下标与i之间的联系,即ndir = (dir + i + 3) % 4,这样就能够在不同的方向上满足当way的i从0到3枚举时总是满足左,前,右,后的顺序,就不用分别讨论了。。。。。恩。。。尴尬的就是在做的时候,memset对map初始化了两次,总是runtime error,找了一下午的错。。。智障了。。。。
#include<stdio.h> 
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<queue>
using namespace std;

char map[50][50];
int book[50][50];
int way[4][2] = {{0,-1},{-1,0},{0,1},{1,0}};
int flag;
int step;
int sx,sy,ex,ey;
int r,c;
int t;

struct node
{
	int x,y;
	int step;
};

void dfs(int x,int y,int dir)
{
	if (x == ex && y == ey)
	{
		flag = 1;
		printf("%d ",step+1);
		return ;
	}

	for(int i=0; i<4; i++)
	{
		int ndir = (dir + i + 3) % 4;
		int nx = x + way[ndir][0];
		int ny = y + way[ndir][1];
		
		if (nx < 0 || ny < 0 || nx >=r || ny >= c)
			continue;
		if (map[nx][ny] != '#')
		{
			step++;
			dfs(nx,ny,ndir);
			if (flag)	
				return ;
			step++;	
		}
	} 
}

/*
int dfs(int x, int y, int dir, int step) 
{
    for(int k = 0; k < 4; k++) 
	{
        if(x == ex && y == ey) return (step + 1);
        int ndir = (dir + k + 3) % 4;
        int nx = x + way[ndir][0];
        int ny = y + way[ndir][1];
        if(nx < 0 || ny < 0 || nx >= r || ny >= c) 
			continue;
        if (map[nx][ny] != '#')
   	    	return dfs(nx,ny,ndir,step+1);
    }
}
*/
void bfs()
{
	queue<node>q;
	node cur,next;
	
	book[sx][sy] = 1;
	cur.x = sx;
	cur.y = sy;
	cur.step = 1;
	q.push(cur);
	
	while(!q.empty())
	{
		cur = q.front();
		q.pop();
		
		if (cur.x == ex && cur.y == ey)
		{
			printf("%d\n",cur.step);
			return ;
		}
		
		for(int i=0; i<4; i++)
		{
			next.x = cur.x + way[i][0];
			next.y = cur.y + way[i][1];
			
			if (next.x < 0 || next.y < 0 || next.x >= r || next.y >= c)
				continue;
			if (map[next.x][next.y] != '#' && book[next.x][next.y] == 0)
			{
				book[next.x][next.y] = 1;
				next.step = cur.step + 1;
				q.push(next);	
			} 
		}	
	} 
}

int main()
{
	scanf("%d",&t);
	while(t--)
	{
		memset(map,0,sizeof(map));
		memset(book,0,sizeof(book));
		scanf("%d%d",&c,&r);
		getchar();
		for(int i=0; i<r; i++)
		{
			scanf("%s",map[i]);
			for(int j=0; j<c; j++)
			{
				if (map[i][j] == 'S')
				{
					sx = i;
					sy = j;
				}
				if (map[i][j] == 'E')
				{
					ex = i;
					ey = j;
				}
			}
		}
		step = flag = 0;
		dfs(sx,sy,1);	
	//	printf("%d ",dfs(sx,sy,1,0));
		bfs();
	}
	
	return 0;
}


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值