深度优先搜索及例题《基础》 洛谷

目录

目录

深度优先搜索

基本概念

算法思想

                  模板 

P1706 全排列问题

P1219 [USACO1.5]八皇后 Checker Challenge

 P1605 迷宫

P1101 单词方阵



深度优先搜索

基本概念

深度优先搜索算法(Depth First Search,简称DFS):一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n)。

算法思想

回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。 

//模板 

void dfs(int step)
{
        判断边界
        {
            相应操作
        }
        尝试每一种可能
        {
               满足check条件
               标记
               继续下一步dfs(step+1)
               恢复初始状态(回溯的时候要用到)
        }
} 

 

P1706 全排列问题

深度优先搜索及例题《基础》 洛谷_第1张图片

#include
#include
int a[15];
int b[15];
int n;
void dfs(int);
int main()
{
    scanf("%d",&n);
    dfs(1);
    return 0;
}
void dfs(int m)
{
    int j;
    if(m==n+1)                    //边界,输出
    {
        for(int i=1;i<=n;i++)
            printf("%5d",a[i]);
        printf("\n");
        return ;
    }
      
    for(j=1;j<=n;j++)               //相当于遍历寻找
    {
        if(b[j]==0)
        {
            a[m]=j;
            b[j]=1;
            dfs(m+1);
            b[j]=0;        //回溯
        }
    }

}

P1219 [USACO1.5]八皇后 Checker Challenge

深度优先搜索及例题《基础》 洛谷_第2张图片

深度优先搜索及例题《基础》 洛谷_第3张图片

#include
int a[40];
int lie[40];
int u[40];
int v[40];
int n;
int cnt;                        //全局变量方便全局输入
void dfs(int);
int main()
{
    scanf("%d",&n);
    dfs(1);
    printf("%d\n",cnt);
    return 0;
}

void dfs(int x)
{
    int i;
    if(x==n+1)                  //边界,递归出口
    {
        cnt++;
        if(cnt<=3)                //输出前三行
        {
            for(i=1;i<=n;i++)
                printf("%d ",a[i]);
            printf("\n");
        }
    }
    for(i=1;i<=n;i++)                //遍历,从第一列到第n列,记住,x为行数
    {
        if(!lie[i] && !u[x-i+n] && !v[x+i])    //标记过的就不管,这三个式子用来衡量坐标关系
        {
            lie[i]=1;
            u[x-i+n]=1;
            v[x+i]=1;                        //标记
            a[x]=i;                          //a数组用来记住x行的i列,方便输出
            dfs(x+1);                        //接下来这个递归就是更进一步
            lie[i]=0;                        //重新标记为0,回溯
            u[x-i+n]=0;
            v[x+i]=0;
        }
   }
}

 P1605 迷宫

深度优先搜索及例题《基础》 洛谷_第4张图片

#include
int n,m,t,kx,ky,fx,fy,cnt;
int vis[10][10];                  //原地图的起点和出口标记
int mp[10][10];                  //障碍物的地图标记
int xx[]={1,0,-1,0};
int yy[]={0,1,0,-1};            //横纵坐标的方向改变
void dfs(int,int);
int main()
{
    int tempx,tempy;
    scanf("%d %d %d",&n,&m,&t);
    scanf("%d %d %d %d",&kx,&ky,&fx,&fy);

    while(t--)                    //标记障碍物
    {
        scanf("%d %d",&tempx,&tempy);
        mp[tempx][tempy]=1;
    }
    vis[kx][ky]=1;                //起点
    dfs(kx,ky);
    printf("%d\n",cnt);
    return 0;
}

void dfs(int x,int y)
{
    int i,dx,dy;
    if(x==fx && y==fy)
    {
        cnt++;return ;
    }
    for(i=0;i<4;i++)
    {
        dx=xx[i]+x;
        dy=yy[i]+y;
        if(dx>=1 && dx<=n && dy>=1 && dy<=m && !vis[dx][dy] &&!mp[dx][dy])    //判断
        {
            vis[dx][dy]=1;
            dfs(dx,dy);
            vis[dx][dy]=0;
        }
    }


}

P1101 单词方阵

题目描述

给一n \times nn×n的字母方阵,内可能蕴含多个“yizhong”单词。单词在方阵中是沿着同一方向连续摆放的。摆放可沿着 88 个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间可以交叉,因此有可能共用字母。输出时,将不是单词的字母用*代替,以突出显示单词。例如:

输入:
    8                     输出:
    qyizhong              *yizhong
    gydthkjy              gy******
    nwidghji              n*i*****
    orbzsfgz              o**z****
    hhgrhwth              h***h***
    zzzzzozo              z****o**
    iwdfrgng              i*****n*
    yyyygggg              y******g

深度优先搜索及例题《基础》 洛谷_第5张图片

输入输出样例

输入 #1复制

7
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa
aaaaaaa

输出 #1复制

*******
*******
*******
*******
*******
*******
*******

输入 #2复制

8
qyizhong
gydthkjy
nwidghji
orbzsfgz
hhgrhwth
zzzzzozo
iwdfrgng
yyyygggg

输出 #2复制

*yizhong
gy******
n*i*****
o**z****
h***h***
z****o**
i*****n*
y******g
#include
#include
#define maxn 110
int mp[maxn][maxn];
char vis[maxn][maxn];
int n;
int xx[]={1,1,1,0,0,-1,-1,-1};
int yy[]={-1,0,1,1,-1,0,1,-1};        //八个方向
char str[]="yizhong";

void dfs(int,int);
int main()
{
    int i,j;
    scanf("%d",&n);
    getchar();
    for(i=0;i=0 && dx=0 && dy

你可能感兴趣的:(c语言的学习,深度优先,算法)