这道题可以用深搜(回溯)来写,相信大部分人都是这么想的,但是有些人可能在一些地方饶了半天,所以这里就贴一下我的思路,个人觉得自己的很好懂,除了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<n;i++){
for (int j=0;j<n;j++)
if (used[i][j])//如果是我们打过标记的,即是可以连成yizhong的坐标
cout<<s[i][j];//就原样输出
else cout<<'*';//否则就变成'*'
cout<<endl;
}
}

下面贴上完整代码

#include <iostream>
#include <cstring>
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;i++){
        for (int j=0;j<n;j++)
            if (used[i][j])
                cout<<s[i][j];
            else cout<<'*';//这里注意,注意
    }
}
int main ()
{
    cin>>n;//输入n
    memset(tx,-1,sizeof(tx));//将每个路径都记为-1
    memset(ty,-1,sizeof(ty));
    for (int i=0;i<n;i++)
        for (int j=0;j<n;j++)
            cin>>s[i][j];
    for (int i=0;i<n;i++)
        for (int j=0;j<n;j++)
            if (s[i][j]==key[0])//如果找到了符合条件的开头字符'y'
                start (i,j);//先进行处理
    print();//输出
    return 0;
}

洛谷 P1101-题解的更多相关文章

  1. 洛谷 P1101 单词方阵

    题目链接 https://www.luogu.org/problemnew/show/P1101 题目描述 给一n×n的字母方阵,内可能蕴含多个"yizhong"单词.单词在方阵中 ...

  2. [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码

    [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...

  3. 洛谷P5759题解

    本文摘自本人洛谷博客,原文章地址:https://www.luogu.com.cn/blog/cjtb666anran/solution-p5759 \[这道题重在理解题意 \] 选手编号依次为: \ ...

  4. 关于三目运算符与if语句的效率与洛谷P2704题解

    题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最 ...

  5. 洛谷——P1101 单词方阵

    https://www.luogu.org/problem/show?pid=1101#sub 题目描述 给一nXn的字母方阵,内可能蕴含多个“yizhong”单词.单词在方阵中是沿着同一方向连续摆放 ...

  6. c++并查集配合STL MAP的实现(洛谷P2814题解)

    不会并查集的话请将此文与我以前写的并查集一同食用. 原题来自洛谷 原题 文字稿在此: 题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. ...

  7. 洛谷P2607题解

    想要深入学习树形DP,请点击我的博客. 本题的DP模型同 P1352 没有上司的舞会.本题的难点在于如何把基环树DP转化为普通的树上DP. 考虑断边和换根.先找到其中的一个环,在上面随意取两个点, 断 ...

  8. 【洛谷P1101】单词方阵

    题目大意:给一 \(n \times n\) 的字母方阵,内可能蕴含多个 \("yizhong"\) 单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着 8 个方向的任一方向, ...

  9. 【洛谷】题解 P1056 【排座椅】

    题目链接 因为题目说输入保证会交头接耳的同学前后相邻或者左右相邻,所以一对同学要分开有且只有一条唯一的通道才能把他们分开. 于是可以吧这条通道累加到一个数组里面.应为题目要求纵列的通道和横列的通道条数 ...

  10. 洛谷P3572题解

    这道题实在是一道 毒瘤 题,太坑爹了.那个写 \(deque\) 的题解亲测只有80分,原因 不言而明 ,这道题居然 丧心病狂 到 卡STL . 好了,不吐槽了,进入正题 题目分析: 这是一道十分 简 ...

随机推荐

  1. 自定义QT窗口部件外观之QStyle

    自定义QT窗口部件外观 重新定义Qt内置窗口部件的外观常用的方法有两种:一是通过子类化QStyle 类或者预定义的一个样式,例如QWindowStyle,来定制应用程序的观感:二是使用Qt样式表. Q ...

  2. Qt4.8.6详细安装步骤(使用了i686-4.8.2-release-posix-dwarf-rt_v3-rev3,手动设置gcc和gdb)非常清楚 good

    摘要 在网上查看了很多篇关于Qt 4的安装方法,都是以前很久的帖子,所以就想按自己的方式重新总结一下,希望可以帮助到大家. Qt5的安装比较简单只需要下载一个文件qt-opensource-windo ...

  3. XP下安装ubuntu

    一,环境说明 dell vostro 1400笔记本,winxp sp3操作系统,ubuntu-9.10-desktop-i386.iso 写这篇随笔的时候我用的已经是ubuntu了. 我是在我的移动 ...

  4. asp.net core系列 66 Dapper介绍--Micro-ORM

    一.概述 目前对于.net的数据访问ORM工具很多,EF和EF Core是一个重量级的框架.最近在搭建新的项目架构,来学习一下轻量级的数据访问ORM工具Dapper.Dapper支持SQL Serve ...

  5. 29 z-index

    这个东西非常简单,它有四大特性,每个特性你记住了,页面布局就不会出现找不到盒子的情况. z-index 值表示谁压着谁,数值大的压盖住数值小的, 只有定位了的元素,才能有z-index,也就是说,不管 ...

  6. MAC电脑修改Terminal以及vim高亮显示

    1. Terminal高亮显示 编辑~/.bash_profile文件,在末尾增加两行: export CLICOLOR= export LSCOLORS=exfxcxdxcxegedabagacad ...

  7. C# RESTful API 访问辅助类

    REST 全称是 Representational State Transfer,有人说它是一种风格,并非一种标准,个人觉得挺有道理.它本身并没有创造新的技术.组件与服务,更像是告诉大家如何更好地使用 ...

  8. 长春理工大学第十四届程序设计竞赛(重现赛)J

    J.Printout 题目:链接:https://ac.nowcoder.com/acm/contest/912/J 题目: 小r为了打校赛,他打算去打字社打印一份包含世界上所有算法的模板. 到了打字 ...

  9. 10月17日 JS开始日~

    1.变量提升 变量提升是浏览器的一个功能,在运行js代码之前,浏览器会给js一个全局作用域,叫window, window分为两个模块,一个叫做内存模块,一个叫做运行模块,内存模块找到当前作用域下的 ...

  10. asp.net core 2.2 生产环境直接更新View页面并立即生效

    有的时候我们会直接在生产环境上更新页面文件,比如更改了JS代码,CSS代码或页面的文案,布局等.这种没有改到后台代码的情况一般就是直接发布页面文件了,在asp.net core 2.2以前的版本(没有 ...