YTU3148: 搜索基础之迷宫问题栈 自己的弱点多看两眼

3148: 搜索基础之迷宫问题

从起点开始遍历,上下左右四个方向,如果找到了能走的方向,从这个方向再往下走,没找到说明走到这个点走到了一个死胡同,这个点需要回退。
按上面的算法,保存在栈中的就是所有路径。

因为有上下左右四个方向,如果找到一个,就不要再继续找这个点的其他方向了,而是将这个新找到的点入栈,再从这个点出发去DFS其他点。

每找到一个点,需要设置这个点不能走了,可以将这个点设置为墙。因为这个点走也是死胡同,所以把这个点设置为墙下次再走的时候就不要走了,如果将这个点在重新设置为0 (可以走),就会死循环。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
typedef pair<int,int> PII;
const int N = 10;
int fx[N] = {0,-1,0,1};
int fy[N] = {1,0,-1,0};
int a[10][10];
PII res[100];
int xe,ye;
stack<PII> s;
void print()
{
    int k=0;
    while(!s.empty())
    {
        
        PII top = s.top();
        s.pop();
        res[++k] = {top.first,top.second};
    }
    for(int i=k;i>0;i--)
        cout<<"("<<res[i].first-1<<", "<<res[i].second-1<<")\n";
}
void dfs()
{
    s.push({1,1});
    a[1][1] = -1;
    while(!s.empty())
    {
        PII top;
        top = s.top();
        int x0,y0;
        x0=top.first;
        y0=top.second;
        bool find = false;
        for(int i=0;i<4 &&!find;i++)
        {
            int x,y;
            x = x0 + fx[i];
            y = y0 + fy[i];
            if(x<1||y<1||x>5||y>5||a[x][y])
                continue;
            find = true;
            a[x][y] = 1;
            s.push({x,y});
            if(x==xe&&y==ye)
            {
                print();
            }
        }
        if(!find) 
        {
            s.pop();
        }
    }
}
int main()
{
    int n=5;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
            cin>>a[i][j];
    }
    xe = ye = 5;
    dfs();
}

用递归做
建议反复观看

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
typedef pair<int,int> PII;
const int N = 10;
int a[N][N];
int fx[4] = {0,-1,0,1};
int fy[4] = {1,0,-1,0};
int n;
int xe = 4,ye=4;
stack<PII> s;
vector<PII>res;
void print()
{
    
    while(!s.empty())
    {
        PII top = s.top();
        s.pop();
        int x=top.first;
        int y=top.second;
        res.push_back(top);
    }

   for(int i=res.size()-1;i>=0;i--)
    cout<<"("<<res[i].first<<", "<<res[i].second<<")\n";
}

bool found  = false;
void dfs(int x,int y)
{

    if(x<0||y<0||x>4||y>4||a[x][y])
       {
           a[x][y] = 1;
            return;
       }
    if(x==xe&&y==ye)
     {
        found = true;
        return;
     }
    a[x][y] = 1;
    for(int i=0;i<4 && ! found;i++)	//如果没有这个 !found,就算已经找了出口也还会继续递归。!found是找到了之后就不要再找别的路径了。
    {
        int xto,yto;
        xto = x+fx[i];
        yto = y+fy[i];
        dfs(xto,yto); 
        if(found) res.push_back({xto,yto});   
    }
}
int main()
{
    n=5;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            cin>>a[i][j];
    dfs(0,0);
    cout<<"(0, 0)\n";
    for(int i=res.size()-1;i>=0;i--)
        cout<<"("<<res[i].first<<", "<<res[i].second<<")\n";
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值