关于dfs搜索和方向数组的初识

     本人在刷题网站上做过的一道题:

题目描述

给一n×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

输入格式

第一行输入一个数nn。(7 \le n \le 100,7≤n≤100)。

第二行开始输入n \times nn×n的字母矩阵。

输出格式

突出显示单词的n \times nn×n矩阵。

输入输出样例

输入 #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

这次就是主要想写一写我对dfs搜索算法的初步认识和对方向数组的理解,

int u[8]={-1,-1,0,1,1,1,0,-1}, r[8]={0,1,1,1,0,-1,-1,-1};

(有没有刚开始开到这个一脸懵的,如果理解的话,可以跳过下面的解释) 重点就是这两个方向数组,本题中我们都知道有八个方向可以选择,首先我们假设一个位置(3,3), 那么他就会有八个方向可以选择,这里建立了两个数组,分别对应了横纵坐标,我们每次选一个u[]里的元素和r[]里的元素可以分别对应一个方向,单应注意要对应下标相同(即u[0]和r[0]),对(3,3)坐标进行对应的加减,也就是这一步: int xx=x+u[p],yy=y+r[p]; 这就达到了八个方向搜索的要求,

之后要使其顺序可以连成一个单词,可以以要搜索的下一个单词为条件,这里我也是参考了大佬的思路,采用了字符数组 le['y']='i'; le['i']='z'; le['z']='h'; le['h']='o'; le['o']='n'; le['n']='g'; 剩下就是dfs的基本思路了。

最后附上代码:

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
char s[105][105];
bool v[101][101];
char le[201];
int n;
int u[8]={-1,-1,0,1,1,1,0,-1},r[8]={0,1,1,1,0,-1,-1,-1};//u表示x轴书方向表示x,横方向表示y
bool f(int x,int y,char ch,int p)
{
    if(ch=='g')
    { v[x][y]=1;
       return 1;
    }

    int xx=x+u[p],yy=y+r[p];
    if(xx>=1 && yy>=1 && xx<=n && yy<=n && s[xx][yy]==le[ch])
      {
          if(f(xx,yy,le[ch],p))
          {   v[x][y]=1;
              return 1;
          }
      }
    return 0;

}
int main()
{
    cin>>n;
    le['y']='i';
    le['i']='z';
    le['z']='h';
    le['h']='o';
    le['o']='n';
    le['n']='g';
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        cin>>s[i][j];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
    {
        if(s[i][j]=='y')
        {
            for(int k=0;k<=7;k++)//八个方向
            {
                if(f(i,j,'y',k))
                    v[i][j]=1;
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
    {
        if(v[i][j])
            cout<<s[i][j];
        else
            cout<<'*';

    }
    cout<<"\n";
    }

    return 0;

}
最后再强调一个事情,如果说这里的n为全局变量的话,那么如果在main函数里再定义一次的话可能会出错,具体应该和变量生存问题有关,可以百度一下。

 

最后,我想跟广大刚学习编程的同胞们说一句;有时候遇到不会的东西不要着急问别人,自己琢磨出来的和别人强喂给你的收货绝对不一样,还请各位三思而后问!!!

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
深度优先搜索DFS)是一种图遍历算法,适用于解决图的连通性、遍历和寻找路径等问题。在应用DFS算法时,常常需要将图的结构表示为数组。 建立一个DFS深度优先搜索数组时,可以按照以下步骤进行操作: 1. 首先,创建一个与图中顶点数量相等的数组,用于记录每个顶点的访问状态。初始时,将所有的数组元素初始化为未访问状态。 2. 然后,选择一个起始顶点,将其标记为已访问,并将该顶点入栈。 3. 从起始顶点开始,循环执行以下步骤:弹出栈顶元素(当前顶点),并输出该顶点的值; 4. 遍历该顶点的所有邻接顶点,若某个邻接顶点未被访问,则将其标记为已访问,并将其入栈。 5. 若当前顶点没有未被访问的邻接顶点,则继续弹出栈顶元素,即回溯到上一个顶点,直到栈为空。 6. 当图中所有顶点都被访问过后,DFS深度优先搜索结束。 通过上述步骤,我们可以将图的结构以数组的形式表示,并使用DFS算法进行遍历。在数组中,每个元素代表一个顶点,其对应的值表示该顶点是否已经被访问。通过设置一个栈来保存待访问的顶点,不断地出栈和入栈的操作,实现了DFS算法的深度遍历特性。 需要注意的是,数组的索引可以用来唯一标识顶点,索引值对应的元素则表示该顶点的访问状态。此外,可以根据具体需求,对数组进行扩展,以记录其他需要的信息,比如顶点的父节点、访问时间等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值