营救公主-广度优先遍历算法

公主被魔王抓走了,王子需要拯救出美丽的公主。他进入了魔王的城堡,魔王的城堡是一座很大的迷宫。为了使问题简单化,我们假设这个迷宫是一个N*M的二维方格。迷宫里有一些墙,王子不能通过。王子只能移动到相邻(上下左右四个方向)的方格内,并且一秒只能移动一步,就是说,如果王子在(x,y)一步只能移动到(x-1,y),(x+1,y),(x,y-1),(x,y+1)其中的一个位置上。地图由‘S’,‘P’,‘.’,‘*’四种符号构成,‘.’表示王子可以通过,‘*’表示墙,王子不能通过;'S'表示王子的位置;‘P’表示公主的位置;T表示公主存活的剩余时间,王子必须在T天内到达公主的位置,才能救活公主。如下图所示:



上面是一个5*5的迷宫,红色箭红色箭头标识的是从S到P的一条路径。这条路径是最短的一条。如果题目中给的T是5的话,那么就无法救出公主。

 

/**************************************************************************
Description 
每组测试数据以三个整数N,M,T(0<n, m≤20, t>0)开头,分别代表迷宫的长和高,以及公主能坚持的天数。
紧接着有M行,N列字符,由".","*","P","S"组成。其中 "." 代表能够行走的空地。 "*" 代表墙壁,王子不能从此通过。
"P" 是公主所在的位置。 "S" 是王子的起始位置。 每个时间段里王子只能选择“上、下、左、右”任意一方向走一步。
Prototype
int SSaveP (int *maze[], int M, int n, int t)
Input Param
maze            迷宫布局(这里用二维数组实现布局)      
M               迷宫(数组)行数
N               迷宫(数组)列数
T               公主能坚持的天数
Output Param

Return Value
0         可以救出公主
-1        不可以救出公主

****************************************************************************/

#include<stdio.h> 
#include<string.h>  
#include "malloc.h"

typedef struct _PathNode
{
	int m_nRow;
	int m_nCol;
	int m_nValue;
	struct _PathNode *pNext;
}PathNode;

PathNode *g_OpenHead = {0};
PathNode *g_OpenTail;
PathNode *g_CloseHead = {0};
PathNode *g_CloseTail;

int g_ArrowRow = 0;
int g_ArrowCol = 0;

int GetStartPoint(char* visited,int* nStartRow,int* nStartCol);
void InsertStartPoint(int nStartRow,int nStartCol);
void Init();
bool SearchPrincess(char* visited,int t);
bool IsThisPrincess(char* visited,PathNode* pNode,int t);
void DevelopNode(char* visited,PathNode* pNode);
void InsertNode(int nRow,int nCol,int nValue);
bool IsLeagalNode(char* visited,int nRow,int nCol);
void CloseSearchedNode();

int SSavep(char *visited, int t, int n, int m)
{ 
	// 这里面添加函数功能
	if (NULL == visited)
	{
		return -1;
	}
	if (NULL != g_OpenHead || NULL != g_CloseHead)
	{
		Init();
	}

	int nStartRow = 0;
	int nStartCol = 0;

	g_ArrowRow = m;
	g_ArrowCol = n;	

	if (0 != GetStartPoint(visited,&nStartRow,&nStartCol))
	{
		return -1;
	}
	InsertStartPoint(nStartRow,nStartCol);
	if (false == SearchPrincess(visited,t))
	{
		Init();
		return -1;
	}
	Init();
	return 0;
} 

bool SearchPrincess(char* visited,int t)
{
	PathNode* pTemp = g_OpenHead;

	if (NULL == pTemp)
	{
		return false;
	}
	if (true == IsThisPrincess(visited,pTemp,t))
	{
		return true;
	}
	DevelopNode(visited,pTemp);
	CloseSearchedNode();
	if (false == SearchPrincess(visited,t))
	{
		return false;
	}
	return true;
}

void CloseSearchedNode()
{
	PathNode* pTemp = g_OpenHead;

	if (NULL == g_CloseHead)
	{
		g_CloseHead = pTemp;
		g_CloseTail = pTemp;
	}
	else
	{
		g_CloseTail->pNext = pTemp;
		g_CloseTail = pTemp;		
	}
	g_OpenHead = g_OpenHead->pNext;
	pTemp->pNext = NULL;	
}

void DevelopNode(char* visited,PathNode* pNode)
{
	if (true == IsLeagalNode(visited,pNode->m_nRow-1,pNode->m_nCol))
	{
		InsertNode(pNode->m_nRow-1,pNode->m_nCol,pNode->m_nValue+1);
	}
	if (true == IsLeagalNode(visited,pNode->m_nRow,pNode->m_nCol+1))
	{
		InsertNode(pNode->m_nRow,pNode->m_nCol+1,pNode->m_nValue+1);
	}
	if (true == IsLeagalNode(visited,pNode->m_nRow+1,pNode->m_nCol))
	{
		InsertNode(pNode->m_nRow+1,pNode->m_nCol,pNode->m_nValue+1);	
	}
	if (true == IsLeagalNode(visited,pNode->m_nRow,pNode->m_nCol-1))
	{
		InsertNode(pNode->m_nRow,pNode->m_nCol-1,pNode->m_nValue+1);
	}	
}

void InsertNode(int nRow,int nCol,int nValue)
{
	PathNode* pNode;

	pNode = (PathNode*)malloc(sizeof(PathNode));
	pNode->pNext = NULL;
	pNode->m_nRow = nRow;
	pNode->m_nCol = nCol;
	pNode->m_nValue = nValue;

	g_OpenTail->pNext = pNode;
	g_OpenTail = pNode;
}

bool IsLeagalNode(char* visited,int nRow,int nCol)
{
	PathNode* pTemp1 = g_CloseHead;
	PathNode* pTemp2 = g_OpenHead;

	if (nRow < 0 || nCol < 0 || nRow >= g_ArrowRow || nCol >= g_ArrowCol)
	{
		return false;
	}
	if (*(visited+(nRow*g_ArrowCol)+nCol) == '*')
	{
		return false;
	}
	while (NULL != pTemp1)
	{
		if (pTemp1->m_nRow == nRow && pTemp1->m_nCol == nCol)
		{
			return false;
		}
		pTemp1 = pTemp1->pNext;
	}
	while (NULL != pTemp2)
	{
		if (pTemp2->m_nRow == nRow && pTemp2->m_nCol == nCol)
		{
			return false;
		}
		pTemp2 = pTemp2->pNext;
	}

	return true;
}

bool IsThisPrincess(char* visited,PathNode* pNode,int t)
{
	if (*(visited+(pNode->m_nRow*g_ArrowCol)+pNode->m_nCol) == 'P' && pNode->m_nValue <= t)
	{
		return true;
	}
	return false;
}

int GetStartPoint(char* visited,int* nStartRow,int* nStartCol)
{
	for (int i=0;i<g_ArrowRow;i++)
	{
		for (int j=0;j<g_ArrowCol;j++)
		{
			if (*(visited+i*g_ArrowCol+j) == 'S')
			{
				*nStartRow = i;
				*nStartCol = j;
				return 0;
			}
		}
	}
	return -1;
}

void InsertStartPoint(int nStartRow,int nStartCol)
{
	PathNode* pNode;

	pNode = (PathNode*)malloc(sizeof(PathNode));
	pNode->pNext = NULL;
	pNode->m_nRow = nStartRow;
	pNode->m_nCol = nStartCol;
	pNode->m_nValue = 0;

	g_OpenHead = pNode;
	g_OpenTail = pNode;
}

void Init()
{
	PathNode* pTemp1 = g_OpenHead;
	PathNode* pTemp2 = g_CloseHead;

	while (NULL != pTemp1)
	{
		g_OpenHead = g_OpenHead->pNext;
		free(pTemp1);
		pTemp1 = g_OpenHead;
	}
	while (NULL != pTemp2)
	{
		g_CloseHead = g_CloseHead->pNext;
		free(pTemp2);
		pTemp2 = g_CloseHead;
	}
	g_ArrowRow = 0;
	g_ArrowCol = 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值