公主被魔王抓走了,王子需要拯救出美丽的公主。他进入了魔王的城堡,魔王的城堡是一座很大的迷宫。为了使问题简单化,我们假设这个迷宫是一个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;
}