zoukankan      html  css  js  c++  java
  • 深度优先搜索

    迷宫图可能比较抽象,把迷宫图按照45度倾斜就是一棵树一样的。现在来看这棵树
    首先肯定是从起点1开始的 深度优先是按照一条链跑到底 所以就是按照
    1 -> 2 -> 3 ->6
    1 -> 2 -> 3 ->5
    1 -> 2 -> 4 ->8
    1 -> 2 -> 4 ->7
    每次都从开始跑到最后不能跑的边界为止
    实现方法 堆栈实现
    具体思路:
    首先把起点入栈,然后按照方向顺序,如果下一个方向那个坐标没有跑过或者没有障
    碍直接入栈
    从1开始入栈,2也入栈,先看看3,可行就入栈,
    重点是如果6和5我都不能顺利到达,就直接把3出栈,因为此时它没有路可以走了
    那么就可以看2的另外一条边4 如下图

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int INF=0x3f3f3f3f;
    const int maxn=100;
    int dx[8]={-1,0,1,-1,1,-1,0,1};///x轴的偏移量
    int dy[8]={1,1,1,0,0,-1,-1,-1};///y轴的偏移量
    struct Node {
        int x,y;
        int idx;
    }N[maxn];
    int M[maxn][maxn];///记录迷宫
    bool vis[maxn][maxn];///标记数组  已经通过的点为1
    int top=0;///栈顶指针
    
    int main()
    {
        freopen("1.txt","r",stdin);
        int n;
        scanf("%d",&n);
        for (int i=0;i<n;++i)
        {
            for (int j=0;j<n;++j)
            {
                scanf("%d",&M[i][j]);
            }
        }
        top = 1;///代表栈中的元素个数
        N[top] = Node{0,0,-1};///输入x y idx 整个打包输入
        while (top!=0)///栈内元素不为空
        {
            int d=-1;///重点
            //cout<<d<<endl;
            while ((++d)<8)///注意点
            {
               ///cout<<d<<endl;
               int xx = N[top].x+dx[d];
               int yy = N[top].y+dy[d];
               //cout<<d<<endl;
               ///cout<<xx<<' '<<yy<<endl;
               if (xx<0||xx>=n||yy<0||yy>=n||M[xx][yy]==1||vis[xx][yy]==1)continue;
               else
               {
                // cout<<top<<endl;
                  N[++top].x=xx;///找到了直接入栈
                  N[top].y=yy;
                  N[top].idx=d;
                  vis[xx][yy]=1;///标记  找过了的都没有找到就不用回溯 
                  ///回溯  把之前做的标记取消
                  M[xx][yy]=1;///标记
                  ///cout<<xx<<' '<<yy<<endl;
                  break;
               }
            }
            //cout<<1<<' '<<top<<endl;
            if (d == 8){--top;}///没找到出路,当前节点不可行直接出栈
            if (N[top].x == n-1&&N[top].y == n-1)break;///到达终点直接保存栈 然后break
    
        }
        for (int i=1;i<=top;++i)
        {
            printf("%d %d
    ",N[i].x,N[i].y);///直接输出
        }
        return 0;
    }
    /*
    5
    0 1 1 1 1
    1 0 1 1 1
    0 1 0 1 1
    0 1 1 1 1
    0 0 0 0 0
    */
    
    

    易错点 (其实是我de了半天的bug,惊醒一下)
    int d=-1;///重点
    //cout<<d<<endl;
    while ((++d)<8)///注意点
    这里相当于for (int d=0;d<8;++d)
    但是如果直接输出 int d=0;
    while (d<8){++d;}这样的话实际上只有7个数 ,与我们的取八个方向不相符合
    while (d<9){++d;}你强行改成这样的话d会到8,数组会越界
    这边建议看看胡昀霏大佬的修改

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int INF=0x3f3f3f3f;
    const int maxn=100;
    int dx[8]={-1,0,1,-1,1,-1,0,1};
    int dy[8]={1,1,1,0,0,-1,-1,-1};
    struct Node {
        int x,y;
        int idx;
    }N[maxn];
    int M[maxn][maxn];
    bool vis[maxn][maxn];
    int top=0;
    int main()
    {
        //freopen("1.txt","r",stdin);
        int n;
        scanf("%d",&n);
        for (int i=0;i<n;++i)
        {
            for (int j=0;j<n;++j)
            {
                scanf("%d",&M[i][j]);
            }
        }
        top = 1;///代表栈中的元素个数
        N[top].x=0;
        N[top].y=0;
        N[top].idx=-1;
        while (top!=0)
        {
            int d = ++N[top].idx;///由于d是按照顺序来的,所以每次从当前栈顶的方向+1
            //cout<<d<<endl;
            if (d<8)
            {
               int xx = N[top].x+dx[d];
               int yy = N[top].y+dy[d];
               //cout<<d<<endl;
               ///cout<<xx<<' '<<yy<<endl;
               if (xx<0||xx>=n||yy<0||yy>=n||M[xx][yy]==1||vis[xx][yy]==1)continue;///防止越界
               else
               {
                // cout<<top<<endl;
                  N[++top].x=xx;///找到了直接入栈
                  N[top].y=yy;
                  N[top].idx=-1;///由于要遍历每个方向所以要从-1开始
                  vis[xx][yy]=1;
                  M[xx][yy]=1;
                  ///cout<<xx<<' '<<yy<<endl;
               }
    
            }
            else top --;///找到最后一个方向都没找到,证明这个点走不通,直接出栈
            //cout<<1<<' '<<top<<endl;
            if (N[top].x == n-1&&N[top].y== n-1)break;
        }
        for (int i=1;i<=top;++i)
        {
            printf("%d %d
    ",N[i].x,N[i].y);
        }
        return 0;
    }
    /*
    5
    0 1 1 1 1
    1 0 1 1 1
    0 1 0 1 1
    0 1 1 1 1
    0 0 0 0 0
    */
    
    齐芒行,川锋明!
  • 相关阅读:
    用Python完成一个汇率转换器
    鸿蒙如何用JS开发智能手表App
    鸿蒙如何用JS开发智能手表App
    SAP Spartacus SplitViewComponent Migration 的一个具体例子
    SAP Spartacus B2B 页面 Popover Component 的条件显示逻辑
    SAP Spartacus 升级时关于 schematics 的更新
    SAP Spartacus B2B 页面 Disable 按钮的显示原理
    SAP Spartacus B2B 页面 Disable Confirmation 对话框的显示原理
    通过 Feature Level 动态控制 SAP Spartacus 的页面显示
    SAP Commerce Cloud Build Manifest Components
  • 原文地址:https://www.cnblogs.com/qimang-311/p/13754978.html
Copyright © 2011-2022 走看看