博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷 P1101-题解
阅读量:5145 次
发布时间:2019-06-13

本文共 3086 字,大约阅读时间需要 10 分钟。

这道题可以用深搜(回溯)来写,相信大部分人都是这么想的,但是有些人可能在一些地方饶了半天,所以这里就贴一下我的思路,个人觉得自己的很好懂,除了tx和ty那里,但是tx和ty的那种用法对于输出路径的题目一般很实用

这个算是比较简单的吧,题目里给出了具体要找的字符串,我们要做的就是对它进行8个方向的搜索,所以先定一个方向,和要找的字符串

(注,代码前的span...>都不是代码!!)

const char key[8]={'y','i','z','h','o','n','g','\0'};
int dirx[8]={-1,-1,-1,0,0,1,1,1},diry[8]={-1,0,1,-1,1,-1,0,1};

配合着x,y分别是左上,正上,右上,正左,正右,左下,正下和右下

然而最后我们并不是只要是这些关键字就要保留的,所以我们只需记录下我们最后需要输出的坐标

int used[105][105];

但是并不是每一个都需要去搜索的,只要在需要搜索的地方搜索就可以了

那么哪些需要搜索呢,最开始肯定是从字符'y'开始往里搜索啦,然后在开始搜索之前呢,先判断我们下一步往哪个方向进行搜索,这样就不需要每次都各个方向的去找了(废话)

那么就先做个函数对找到的'y'进行确定下一步往哪个方向去找

void start (int x,int y)//最开始找到的'y'的坐标{    int kx,ky,k;//临时坐标    for (k=0;k<8;k++){        kx=x+dirx[k];ky=y+diry[k];//各个方向都进行查找        if (kx<0||ky<0||kx>=n||ky>=n)//不能越界            continue;        if (s[kx][ky]==key[1]){//如果找到了在方向上有'i'就往这个方向继续查找            locx=x;//先记录下我们的出发点            locy=y;            dfs (kx,ky,1,k);        }    }}

接下来是深搜的函数

void dfs (int x,int y,int rank,int fx)//x,y是当前坐标,rank则是记录现在已经找到几个了,fx表示方向{    if (rank==6){used[locx][locy]=1;deal(x,y);return;}//这一步后面会解释,其实是全部找到了就对一路走过来的这几个打上'标记'意味着需要保留    int kx,ky;    kx=x+dirx[fx];ky=y+diry[fx];//临时变量    if (kx<0||ky<0||kx>=n||ky>=n)//防止越界        return;    if (s[kx][ky]==key[rank+1]){        tx[kx]=x;//记录下找到下一个字符的路径,表示kx是从x这来的        ty[ky]=y;        dfs (kx,ky,rank+1,fx);//进行下一步搜索        tx[kx]=ty[ky]=-1;//把路径取消    }}

之后就是我们的deal函数了,deal是对一直能够走到这条路的所有坐标进行处理让他们可以保留原样输出(used[x][y]=1)

void deal (int x,int y){    while (x!=-1&&y!=-1){//如果不是这条路的则是-1,前面定义了        used[x][y]=1;//将当前坐标打上标记        x=tx[x];//回到我们是怎么走过来的,即到上一步的地方去        y=ty[y];    }}

最后顺便带了个输出函数

void print (void){    for (int i=0;i

下面贴上完整代码

#include 
#include
using namespace std;const char key[8]={'y','i','z','h','o','n','g','\0'};char s[105][105];int n,dirx[8]={-1,-1,-1,0,0,1,1,1},diry[8]={-1,0,1,-1,1,-1,0,1},tx[105],ty[105],used[105][105],locx,locy;void deal (int x,int y){    while (x!=-1&&y!=-1){//如果不是这条路的则是-1,前面定义了        used[x][y]=1;//将当前坐标打上标记        x=tx[x];//回到我们是怎么走过来的,即到上一步的地方去        y=ty[y];    }}void dfs (int x,int y,int rank,int fx)//x,y是当前坐标,rank则是记录现在已经找到几个了,fx表示方向{    if (rank==6){used[locx][locy]=1;deal(x,y);return;}//这一步后面会解释,其实是全部找到了就对一路走过来的这几个打上'标记'意味着需要保留    int kx,ky;    kx=x+dirx[fx];ky=y+diry[fx];//临时变量    if (kx<0||ky<0||kx>=n||ky>=n)//防止越界        return;    if (s[kx][ky]==key[rank+1]){        tx[kx]=x;//记录下找到下一个字符的路径,表示kx是从x这来的        ty[ky]=y;        dfs (kx,ky,rank+1,fx);//进行下一步搜索        tx[kx]=ty[ky]=-1;//把路径取消    }}void start (int x,int y)//最开始找到的'y'的坐标{    int kx,ky,k;//临时坐标    for (k=0;k<8;k++){        kx=x+dirx[k];ky=y+diry[k];//各个方向都进行查找        if (kx<0||ky<0||kx>=n||ky>=n)//不能越界            continue;        if (s[kx][ky]==key[1]){//如果找到了在方向上有'i'就往这个方向继续查找            locx=x;//先记录下我们的出发点            locy=y;            dfs (kx,ky,1,k);        }    }}void print (void){    for (int i=0;i
>n;//输入n    memset(tx,-1,sizeof(tx));//将每个路径都记为-1    memset(ty,-1,sizeof(ty));    for (int i=0;i
>s[i][j];    for (int i=0;i

转载于:https://www.cnblogs.com/Morning-Glory/p/9724098.html

你可能感兴趣的文章
js编写时间选择框
查看>>
Java数据结构和算法(四)--链表
查看>>
JIRA
查看>>
小技巧——直接在目录中输入cmd然后就打开cmd命令窗口
查看>>
深浅拷贝(十四)
查看>>
HDU 6370(并查集)
查看>>
BZOJ 1207(dp)
查看>>
PE知识复习之PE的导入表
查看>>
HDU 2076 夹角有多大(题目已修改,注意读题)
查看>>
洛谷P3676 小清新数据结构题(动态点分治)
查看>>
九校联考-DL24凉心模拟Day2T1 锻造(forging)
查看>>
Attributes.Add用途与用法
查看>>
L2-001 紧急救援 (dijkstra+dfs回溯路径)
查看>>
javascript 无限分类
查看>>
spring IOC装配Bean(注解方式)
查看>>
[面试算法题]有序列表删除节点-leetcode学习之旅(4)
查看>>
SpringBoot系列五:SpringBoot错误处理(数据验证、处理错误页、全局异常)
查看>>
kubernetes_book
查看>>
OpenFire 的安装和配置
查看>>
侧边栏广告和回到顶部
查看>>