ACM -- 逃离迷宫

Problem Description

  给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?

 

 

Input

  第1行为一个整数t (1 ≤ t ≤100),表示测试数据的个数,接下来为t组测试数据,每组测试数据中,
  第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'*'表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x1,y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能转的弯数,(x1,y1), (x2, y2)表示两个位置,其中x1,x2对应列,y1,y2对应行。

 

 

Output

  每组测试数据对应为一行,若gloria能从一个位置走到另外一个位置,输出“yes”,否则输出“no”。

 

 

Sample Input

2

5 5

...**

*.**.

.....

.....

*....

1 1 1 1 3

5 5

...**

*.**.

.....

.....

*....

2 1 1 1 3

 

 

Sample Output

no

yes

 

算法思路:

 1. 用一个二维矩阵构造迷宫,-1表示不可通行,0表示可以通行

 2. 先将起始点的值填1,然后进行遍历,当遇到转角的时候将对应的值加上一填入二维矩阵中

 3. 重复如此步骤。

 

#include "iostream"

using namespace std;

#define N 110
int iGroup[N][N];

const int step[5][2] = {{0,0},
						{0,-1},//上
						{0,1},//下
						{-1,0},//左
						{1,0}};//右

typedef struct 
{
	int x;
	int y;
	//int iDirection;
} Point;

Point ptResult[N*N];
int iGroupNum = 0;
int iClumn = 0;
int iRow = 0;
int i;


int DFS() 
{
	Point ptBegin;
	Point ptEnd;
	Point ptRoad;
	Point ptHelp;
	int iWheelNum;

	cin >> iWheelNum;
	cin >> ptBegin.x >> ptBegin.y;
	cin >> ptEnd.x >> ptEnd.y;
// 	int iOldDirection = 0;
// 	int iCurDirection = 0;//1表示上,2表示下,3表示左,4表示右
	int iHead = 0;
	int iTail = 1;
// 	ptBegin.iDirection = 0;
// 	ptEnd.iDirection = 0;

	if (ptBegin.x == ptEnd.x && ptBegin.y == ptEnd.y)
	{
		return 1;
	}

	if (iGroup[ptBegin.y][ptBegin.x] == -1 || iGroup[ptEnd.y][ptEnd.x] == -1)
	{
		return 0;
	}

	//2. 进行遍历查找符合要求的路径
	//Point *ptResult = (Point*)malloc(sizeof(Point) * iRow * iClumn);
	//Point ptVisited[10] = {0};

	ptResult[1] = ptBegin;
	iGroup[ptBegin.y][ptBegin.x] = 1;

	while (iHead < iTail)
	{
		ptRoad = ptResult[++iHead];
		if (iGroup[ptRoad.y][ptRoad.x] - 1 > iWheelNum)
		{
			return 0;
		}

// 		iOldDirection = ptResult[iHead].iDirection;
		for (int i = 1; i < 5; ++i)
		{
			ptHelp = ptRoad;
			do{
				ptHelp.x += step[i][0];
				ptHelp.y += step[i][1];
				//iCurDirection = i;
				if (ptHelp.x == ptEnd.x && ptHelp.y == ptEnd.y)
				{
					return 1;
				}
				if (!iGroup[ptHelp.y][ptHelp.x])
				{
					ptResult[++iTail] = ptHelp;
					iGroup[ptHelp.y][ptHelp.x] = iGroup[ptRoad.y][ptRoad.x] + 1;
				 }
				}while (iGroup[ptHelp.y][ptHelp.x] != -1);
			}
	}
	//释放空间
	//free(ptResult);
	return 0;
}

void MakeMaze() 
{
	char c;
	cin >> iRow >> iClumn;


	//动态开辟空间
	// 		int **iGroup = (int **)malloc(sizeof(int*) * (iRow + 2));
	// 		for (i = 0; i < iClumn + 2; ++i)
	// 		{
	// 			iGroup[i] = (int *)malloc(sizeof(int) * (iClumn + 2));
	// 		}
	// 		
	//1. 构建迷宫
// 	for (i = 0; i < iRow + 2; ++i)
// 	{
// 		iGroup[0][i] = -1;
// 		iGroup[iRow + 1][i] = -1;
// 	}
// 	for (i = 0; i < iClumn + 2; ++i)
// 	{
// 		iGroup[i][0] = -1;
// 		iGroup[i][iClumn + 1] = -1;
// 	}

	for (i = 0; i < N; ++i )
	{
		for (int j = 0; j < N; ++j)
		{
			iGroup[i][j] = -1;
		}
	}

	for (i = 1; i < iRow + 1; ++i)
	{
		for (int j  = 1; j < iClumn + 1; ++j)
		{
			cin >> c;
			if ('.' == c)
			{
				iGroup[i][j] = 0;
			}else if ('*' == c)
			{
				iGroup[i][j] = -1;
			}else
			{
				//cout << "error!" << endl;
				//exit(1);
			}
		}
	}
}

int main()
{
	//读入数据

	
	cin >> iGroupNum;
	while (0 != iGroupNum--)
	{
		MakeMaze();


		if(DFS())
		{
			cout << "yes" << endl;
		}
		else{
			cout << "no" << endl;
		}
	}

	return 1;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值