营救公主(深度优先搜索算法)

Price.h

#ifndef __OJ_H__
#define __OJ_H__

#include <vector>
#include<string.h>
#include <iostream>
#include <stack>
using namespace std;

enum
{
    EAST = 1,
    SOUTH = 2,
    WEST = 3,
    NORTH = 4,
    BLOCK = 4,
};

// 节点坐标类型
typedef struct
{
    // 坐标
    int x;
    int y;
}structLoc;

// 节点类型
typedef struct
{
    // 是否已经标记过,true表示已标记
    bool bMark;
    char chPoint;
}structPoint;

// 栈元素类型
typedef struct
{
    // 搜索深度
    int depth;

    // 坐标
    int x;
    int y;

    // 搜索方向
    int dir;
}StackType;

int SSavep(char *visited, int t, int n, int m);

// 当前节点是否可通
bool IsBlock(structLoc curLoc, vector<vector<structPoint>> vecMaze);

// 节点标记为已走过
void setFootStep(structLoc curLoc, vector<vector<structPoint>>& vecMaze);

// 到达终点
bool IsEnd(structLoc curLoc);

// 下一个节点
void GetNextPoint(int x, int y, structLoc& curLoc, int dir);

// 深度优先搜素
int DepthFirstSearch(structLoc& curLoc, int dir, int idepth, int iTime, StackType sElement, vector<vector<structPoint>>& vecMaze);

#endif

price.cpp

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

// 起点和终点
structLoc PointS, PointP;

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

*/

int SSavep(char *visited, int t, int n, int m)
{
    // 构造迷宫vector;找出S和P的位置
    vector<vector<structPoint> > vecMaze;
    for (int i = 0; i < m; i++)
    {
        vector<structPoint> vecTemp;
        for (int j = 0; j < n; j++)
        {
            if (‘S‘ == visited[(i * n) + j])
            {
                PointS.x = j;
                PointS.y = i;
            }
            if (‘P‘ == visited[(i * n) + j])
            {
                PointP.x = j;
                PointP.y = i;
            }
            structPoint sPoint;
            sPoint.chPoint = visited[(i * n) + j];
            sPoint.bMark = false;
            vecTemp.push_back(sPoint);
        }
        vecMaze.push_back(vecTemp);
    }

    // 当前节点坐标
    structLoc curLoc;
    curLoc.x = PointS.x;
    curLoc.y = PointS.y;

    // 搜索深度
    int iDepth = 0;

    // 栈元素
    StackType sElement;

    // 节点栈
    stack<StackType> stackPoint;
    do
    {
        if (!IsBlock(curLoc, vecMaze))
        {
            setFootStep(curLoc, vecMaze);
            sElement.depth = iDepth;
            sElement.dir = EAST;
            sElement.x = curLoc.x;
            sElement.y = curLoc.y;

            // 当前节点入栈
            stackPoint.push(sElement);
            if (IsEnd(curLoc))
            {
                return sElement.depth > t?-1:0;
            }
            else
            {
                // 下一个节点
                GetNextPoint(sElement.x, sElement.y, curLoc, EAST);
                iDepth++;
            }
        }
        else
        {
            if (!stackPoint.empty())
            {
                // 回退到上一层深度继续搜索
                sElement = stackPoint.top();
                stackPoint.pop();

                // 节点四个方向都不通,弹出栈
                while ((BLOCK == sElement.dir) && (!stackPoint.empty()))
                {
                    sElement = stackPoint.top();
                    stackPoint.pop();
                }

                // 如果还有其他方向没搜索过,换一个方向搜索
                if (BLOCK != sElement.dir)
                {
                    sElement.dir++;
                    stackPoint.push(sElement);
                    GetNextPoint(sElement.x, sElement.y, curLoc, sElement.dir);
                }
            }
        }
    }
    while(!stackPoint.empty());

    // 没有找到通路
    return -1;
}  

bool IsBlock(structLoc curLoc, vector<vector<structPoint>> vecMaze)
{
    // 遇到边界
    if ((curLoc.x < 0)
        || (curLoc.x >= (int)vecMaze.front().size())
        || (curLoc.y < 0)
        || (curLoc.y >= (int)vecMaze.size()))
    {
        return true;
    }

    // 遇到墙
    structPoint sPoint = vecMaze.at(curLoc.y).at(curLoc.x);
    if (sPoint.chPoint == ‘*‘)
    {
        return true;
    }

    // 已经标记过
    if (true == sPoint.bMark)
    {
        return true;
    }
    return false;
}

void setFootStep(structLoc curLoc, vector<vector<structPoint>>& vecMaze)
{
    vecMaze.at(curLoc.y).at(curLoc.x).bMark = true;
}

bool IsEnd(structLoc curLoc)
{
    if ((curLoc.x == PointP.x) && (curLoc.y == PointP.y))
    {
        return true;
    }
    return false;
}

void GetNextPoint(int x, int y, structLoc& curLoc, int dir)
{
    if (EAST == dir)
    {
        curLoc.x = x + 1;
        curLoc.y = y;
    }
    else if (SOUTH == dir)
    {
        curLoc.x = x;
        curLoc.y = y + 1;
    }
    else if (WEST == dir)
    {
        curLoc.x = x - 1;
        curLoc.y = y;
    }
    else if (NORTH == dir)
    {
        curLoc.x = x;
        curLoc.y = y - 1;
    }
    else
    {

    }
}
时间: 2024-10-03 07:48:24

营救公主(深度优先搜索算法)的相关文章

图的深度优先搜索算法DFS

1.问题描述与理解 深度优先搜索(Depth First Search,DFS)所遵循的策略,如同其名称所云,是在图中尽可能"更深"地进行搜索.在深度优先搜索中,对最新发现的顶点v若此顶点尚有未探索过从其出发的边就探索之.当v的所有边都被探索过,搜索"回溯"到从其出发发现顶点v的顶点.此过程继续直至发现所有从源点可达的顶点.若图中还有未发现的顶点,则以其中之一为新的源点重复搜索,直至所有的顶点都被发现.与BFS中源顶点是指定的稍有不同. DFS搜索轨迹Gπ将形成一片

深度优先搜索算法(DFS)以及leetCode的subsets II

深度优先搜索算法(depth first search),是一个典型的图论算法.所遵循的搜索策略是尽可能“深”地去搜索一个图. 算法思想是: 对于新发现的顶点v,如果它有以点v为起点的未探测的边,则沿此边继续探测下去.当顶点v的所有边都已被探寻结束,则回溯到到达点v的先辈节点.以相同方法一直回溯到源节点为止.如果图中还有未被发现的顶点,则选择其中一个作为源顶点,重复以上的过程.最后的结果是一些不相交的深度优先树. leetCode中的应用: Given a collection of integ

深度优先搜索算法

一.深度优先搜索 深度优先搜索算法(Depth First Search),是图论中的经典算法. 深度优先搜索算法是沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当结点所有子结点那一层都被搜索过,再回溯返回到当前结点的邻结点,继续搜索,直到遍历完整棵树.一般采用的是前序遍历,先根然后再左右结点的方式进行. 任何DFS只需要通过下面几步就可以实现,无论是递归还是非递归方式.我给这几步分别做了一个命名,分别是find.forward.done.back. 如下: 1.find(right):在树

深度优先搜索算法的概念

深度优先搜索算法的概念 与广度优先搜索算法不同,深度优先搜索算法类似与树的先序遍历.这种搜索算法所遵循的搜索策略是尽可能"深"地搜索一个图.它的基本思想如下:首先访问图中某一个起始顶点v,然后由v出发,访问与v相邻且未被访问的任一顶点w1,再访问与w1邻接且未被访问的任一顶点w2,-.重复上述过程.当不能再继续向下访问时,依次退回到最近被访问的顶点,若它还有邻接顶点未被访问过,则从该点开始继续上述搜索过程,直到图中所有顶点均被访问过为止(还是举相同的例子,从你开始遍历你的所有亲戚,例如

广度优先、深度优先搜索算法——面试题

广度优先搜索(Breadth-first Search) BFS在求解最短路径或者最短步数上有很多的应用.应用最多的是在走迷宫上. 分析 树的定义本身就是一种递归定义,因此对于树相关的算法题,递归是最好的解决思路(在递归深度允许的情况下). 递归版 public class Solution { public boolean isSymmetric(TreeNode root) { return root==null||isMirror(root.left,root.right); } priv

广度/深度优先搜索算法 - python实现

1. 图 定义:图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合. 简单点的说:图由节点和边组成.一个节点可能与众多节点直接相连,这些节点被称为邻居. 如二叉树就为一个简单的图: 更加详细的信息可参见:https://www.cnblogs.com/polly333/p/4760275.html 2. 算法 1). 广度优先搜索: 广度优先搜索算法(Breadth First Search,BSF

DFS --- Depth First Search 深度优先搜索算法

Depth First Search 原理还是去看<DSAA>,这里着重分析实现策略. 如果对于图这种数据结构不熟悉,这个BFS一般是搞不定的... 下面分别是无向图的邻接表实现和邻接矩阵实现 http://blog.csdn.net/cinmyheart/article/details/41381845 http://blog.csdn.net/cinmyheart/article/details/41370465 --------------------------------------

广度优先和深度优先搜索算法

#include <iostream> #include <stdlib.h> #include <vector> #include <string> #include <queue> #include <stack> using namespace std; //邻接矩阵显示图 void show_graph(vector<vector<int>> &graph) { for (int i = 0;

深度优先搜索算法基础模板

1 void DFS(检索状态) 2 { 3 if(到达目标状态) 4 { 5 ...// 根据题意添加 6 return; 7 } 8 9 if(越界或是不合法状态) return; 10 11 for(扩展方式) 12 { 13 if(扩展方式所达到状态合法) 14 { 15 ....//根据题意来添加 16 标记; 17 DFS(); // 递归调用 18 修改(剪枝); 19 还原标记; 20 //是否还原标记根据题意 21 //如果加上(还原标记)就是 回溯法 22 } 23 } 24