ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

DFS深度搜索

2021-03-04 16:34:05  阅读:110  来源: 互联网

标签:15 int ++ dfs vis step 搜索 DFS 深度


DFS解决迷宫问题

1、问题

在这里插入图片描述

2、原理分析

https://www.bilibili.com/video/BV1bK4y1C7W2?p=1

3、代码实现

#include<cstdio>
using namespace std;

int p,q;//终点坐标
int m,n;//迷宫有m行n列
int min=99999999;
int a[100][100];//1空地,2障碍物
int v[100][100];//0未访问,1已访问

//深度优先搜索函数
void dfs(int x,int y,int step)//x,y为当前点,step为当前步数
{
//判断是否到终点坐标p,q
    if(x==p&&y==q)
    {
        if(step<min)
            min=step;
    }

    //顺时针试探
    //右
    if(a[x][y+1]==1&&v[x][y+1]==0)
    {
        v[x][y+1]=1;
        dfs(x,y+1,step+1);
        v[x][y+1]=0;
    }
    //下
    if(a[x+1][y]==1&&v[x+1][y]==0)
    {
        v[x+1][y]=1;
        dfs(x+1,y,step+1);
        v[x+1][y]=0;
    }
    //左
    if(a[x][y-1]==1&&v[x][y-1]==0)
    {
        v[x][y-1]=1;
        dfs(x,y-1,step+1);
        v[x][y-1]=0;
    }
    //上
    if(a[x+1][y]==1&&v[x+1][y]==0)
    {
        v[x+1][y]=1;
        dfs(x+1,y,step+1);
        v[x+1][y]=0;
    }
    
    return;
}

int main()
{
	int startx,starty;
	scanf("%d%d",&m,&n);
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
			scanf("%d",&a[i][j]);
	}
	scanf("%d%d%d%d",&startx,&starty,&p,&q);
	v[startx][starty]=1;
	dfs(startx,starty,0);
    printf("%d",min);
    
    return 0;
}
/*输入
5 4
1 1 2 1
1 1 1 1
1 1 2 1
1 2 1 1
1 1 1 2
1 1 4 3 
*/

代码优化:用for循环解决四个方向

#include<cstdio>
using namespace std;

int p,q;//终点坐标
int m,n;//迷宫有m行n列
int min=99999999;
int a[100][100];//1空地,2障碍物
int v[100][100];//0未访问,1已访问
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};

//深度优先搜索函数
void dfs(int x,int y,int step)//x,y为当前点,step为当前步数
{
//判断是否到终点坐标p,q
    if(x==p && y==q)
    {
        if(step<min)
            min=step;
    }
    
    for(int k=0;k<=3;k++)
    {
        int tx,ty;//下个点坐标
        tx=x+dx[k];
        ty=y+dy[k];
        if(a[tx][ty]==1 && v[tx][ty]==0)
        {
            v[tx][ty]=1;
            dfs(tx,ty,step+1);
            v[tx][ty]=0;
        }
    }
    
    return;
}

int main()
{
	int startx,starty;
	scanf("%d%d",&m,&n);
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
			scanf("%d",&a[i][j]);
	}
	scanf("%d%d%d%d",&startx,&starty,&p,&q);
	v[startx][starty]=1;
	dfs(startx,starty,0);
    printf("%d",min);
    
    return 0;
}

4、求解思路

  1. 先判断是否到达目标位置,如果到达目标位置,再试探有无其他更短的路径。
  2. 如果没有到达目标位置,则找到下一步可以到达的位置,直到找到目标位置。

蓝桥杯2017初赛迷宫 DFS

https://www.cnblogs.com/-citywall123/p/12316760.html

1、题目描述

X星球的一处迷宫游乐场建在某个小山坡上。它是由10x10相互连通的小房间组成的。
房间的地板上写着一个很大的字母。我们假设玩家是面朝上坡的方向站立,则:
L表示走到左边的房间,R表示走到右边的房间,U表示走到上坡方向的房间,D表示走到下坡方向的房间。
X星球的居民有点懒,不愿意费力思考。他们更喜欢玩运气类的游戏。这个游戏也是如此!
开始的时候,直升机把100名玩家放入一个个小房间内。玩家一定要按照地上的字母移动。
迷宫地图如下:
------------
UDDLUULRUL
UURLLLRRRU
RRUURLDLRD
RUDDDDUUUU
URUDLLRRUU
DURLRLDLRL
ULLURLLRDU
RDLULLRDDD
UUDDUDUDLL
ULRDLUURRR
------------
请你计算一下,最后,有多少玩家会走出迷宫? 而不是在里边兜圈子。

输出

输出一个整数表示答案

提示

为方便理解,可参考此图

img

答案:31

2、代码实现

(1)DFS

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

char a[15][15];
int vis[15][15];
int ans = 0;

void dfs(int i, int j)
{
    if (i < 0 || i>9 || j < 0 || j>9) //迷宫的出口
    {
        ans++;
        return;
    }
    else
    {
        if (vis[i][j])   return; //如果已经搜过,直接返回

        vis[i][j] = 1;   //标记已搜索

        if (a[i][j] == 'L')
            dfs(i, j - 1); 
        if (a[i][j] == 'R') 
            dfs(i, j + 1); 
        if (a[i][j] == 'U') 
            dfs(i - 1, j); 
        if (a[i][j] == 'D') 
            dfs(i + 1, j); 
    }
}
int main()
{
    int i, j;
    for (i = 0; i < 10; i++)
        for (j = 0; j < 10; j++)
            cin >> a[i][j];
            
    for (i = 0; i < 10; i++)
        for (j = 0; j < 10; j++)
        {
            memset(vis, 0, sizeof(vis)); //搜索每一个房间时,初始化搜搜数组
            dfs(i, j);
        }
    cout << ans << endl;
    return 0;
}

(2)暴力

#include<iostream>
#include<queue>
#include<algorithm>
#include<set>
#include<string.h>
using namespace std;
char a[15][15],c[15][15];
int vis[15][15];
int ans = 0;
int main()
{

    for (int i = 0; i < 10; i++)
    {
        for(int j=0;j<10;j++)
        {
            cin>>a[i][j];
            c[i][j]=a[i][j];
        }
    }

    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            int x = i, y = j;
            memset(vis, 0, sizeof(vis));
            while (1)
            {
                
                if (a[x][y] == 'U')
                {
                    x = x - 1;
                    if (x < 0 || x>9 || y < 0 || y>9)
                    {
                        ans++;
                        c[i][j]='#';
                        break;
                    }
                    if (vis[x][y] == 0)
                        vis[x][y] = 1;
                    else
                        break;
                }
                if (a[x][y] == 'L')
                {
                    y = y - 1;
                    if (x < 0 || x>9 || y < 0 || y>9)
                    {
                        ans++;
                        c[i][j]='#';
                        break;
                    }
                    if (vis[x][y] == 0)
                        vis[x][y] = 1;
                    else
                        break;
                }
                if (a[x][y] == 'R')
                {
                    y = y + 1;
                    if (x < 0 || x>9 || y < 0 || y>9)
                    {
                        ans++;
                        c[i][j]='#';
                        break;
                    }
                    if (vis[x][y] == 0)
                        vis[x][y] = 1;
                    else
                        break;
                }
                if (a[x][y] == 'D')
                {
                    x = x + 1;
                    if (x < 0 || x>9 || y < 0 || y>9)
                    {
                        ans++;
                        c[i][j]='#';
                        break;
                    }
                    if (vis[x][y] == 0)
                        vis[x][y] = 1;
                    else
                        break;
                }
                
            }
        }
    }
    cout << ans << endl;
    // for(int i=0;i<10;i++)
    // {
    //     for(int j=0;j<10;j++)
    //         cout<<c[i][j];
    //     cout<<endl;
    // }
    return 0;
}

3、memset函数

作用: 在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法.
头文件:<memory.h>或<string.h>
例子:
把一个char a[20]清零,是 memset(a, 0, 20*sizeof(char));
对int vis[xx]清零,时memset(vis, 0, sizeof(vis));
其中0可以替换成其他参数,就是把结构体或者数组初始化为其他参数的值

标签:15,int,++,dfs,vis,step,搜索,DFS,深度
来源: https://blog.csdn.net/w_45678910/article/details/114371336

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有