C语言之单词方阵——深搜(很好的深搜例题)

题目描述

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

输入格式

第一行输入一个数 n。(7≤n≤100)。

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

输出格式

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

输入输出样例

复制代码
输入
8
qyizhong
gydthkjy
nwidghji
orbzsfgz
hhgrhwth
zzzzzozo
iwdfrgng
yyyygggg

输出

复制代码
*yizhong
gy******
n*i*****
o**z****
h***h***
z****o**
i*****n*
y******g

代码:

cs 复制代码
#include <stdio.h>
#include <string.h>

#define maxn 102

char s[maxn][maxn];//用于存储输入的字符
int vis[maxn][maxn];//判断是否已访问

// 八个方向
int dx[] = {1, -1, 0, 0, 1, -1, -1, 1};
int dy[] = {0, 0, 1, -1, 1, 1, -1, -1};

char ans[] = "izhong";  // 用于匹配 y 之后的 6 个字符
int n;

void fun(int x, int y) {
    for (int i = 0; i < 8; i++) {//有八个方向可以进行搜索
        int flag = 1;//用于判断是否搜索到的7个字符符合题意,只要有一个不符合题意,就不能执行后面的if语句
        int x1 = x, y1 = y;//将第一个元素y的坐标赋值给x1,x2

        // 检查沿着当前方向的下 6 个字符
        for (int j = 0; j < 6; j++) {
            x1 += dx[i];//将该方向搜索到的字符坐标赋值给x1,y1
            y1 += dy[i];
             //有两个直接终止条件
            // 1.越界判断,越界就说明搜索到头了,直接进行下一个方向搜索
            if (x1 < 0 || x1 >= n || y1 < 0 || y1 >= n) {
                flag = 0;
                break;
            }
            //2.搜索这一个方向的时候,发现有一个字符与目标字符不符合,就说明不符合题意,就直接结束
            if (s[x1][y1] != ans[j]) {
                flag = 0;
                break;
            }
        }

        // 如果 7 个字符都符合(包括第一个 y),标记所有位置
       //标记之后,这个一定是输出原字符的。即使有些方向这个位置不符合题意。最后输出*时,就是没有标记的字符
        if (flag == 1) {
            x1 = x;
            y1 = y;
            vis[x1][y1] = 1;            // 标记起始 y
            for (int j = 0; j < 6; j++) {
                x1 += dx[i];
                y1 += dy[i];
                vis[x1][y1] = 1;
            }
        }
    }
}

int main() {
    scanf("%d", &n);
     //特别要注意的是这种字符输入方式
    // 读入 n 行字符串(每行长度为 n)
    for (int i = 0; i < n; i++) {
        scanf("%s", s[i]);  // %s 自动跳过空白符,不会读入换行
    }

    // 初始化 vis 数组
    memset(vis, 0, sizeof(vis));

    // 遍历每个位置,找到 'y' 开头并尝试八个方向
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (s[i][j] == 'y') {
                fun(i, j);
            }
        }
    }

    // 输出结果
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (vis[i][j]) {
                printf("%c", s[i][j]);
            } else {
                printf("*");
            }
        }
        printf("\n");
    }

    return 0;
}

上述题目的代码和之前例题的代码不一样的地方:

1.题目要求的不一样,所以要根据题意如上述定义ans[]。

2.之前是图,所以每次都从第一个位置开始,所以直接在循环后面调用函数,传入参数就是i,j。但是在这道题目里面不能从第一个位置开始,就像上面一样,要加上if条件判断。

注意!!!深搜一定要明确从哪个地方开始搜索,这道题目没有直接给出起始位置,我们就要从题意中揣测我们要搜的是什么。明确这个之后也就会定义ans[]数组的内容了。

3.可以在搜索过程中进行终止条件的书写,如果深搜到某一位置终止了,直接进行break,进行另一个方向的深搜

4.这道题目已访问过的还是能被访问,所以不和传统的深搜题目一样。但输出不同的是只输出搜索出来的符合题意的字符,那我们就需要将符合题意的字符进行标记,最后用这个标记来输出。那怎么判断是一连串的七个字符呢?就是中间没有中断。这刚好想到标志变量flag。

其他的一开始的坐标赋值,新坐标的计算都和传统的深搜一样。

我写的代码:

1.没有搞清楚初始位置,所以ans[]数组肯定就定义错了。

2.没有搞清楚要干的是什么,所以整个深搜函数就很乱。连应该输出的*也在该函数里面。坐标的赋值完全没有按照传统的深搜进行

3.在做这道题目之前一直以为一开始就要写终止条件,但我觉得还是在方向中写终止条件更好。

4.字符的输入也有点不对,这道题目刚好提供了另一种二维数组的字符输入。

下面就是我写的代码:

#include<stdio.h>

#include<string.h>

char word[]="yizhong";

int dx[]={0,1,1,1,0,-1,-1,-1};

int dy[]={1,1,0,-1,-1,-1,0,1};

void dfs(int ch[][100],int n,int m,int x,int y){

if(x<0||x>=n||y<0||y>=m){

return;

}

int i;

for(i=0;i<7;i++){

if(ch[x][y]!=word[i]){

ch[x][y]='*';

}

}

for(i=0;i<7;i++){

int nextx=x+dx[i];

int nexty=y+dy[i];

dfs(ch,visited,n,n,nextx,nexty);

}

}

int main()

{

int n;

scanf("%d",&n);

char ch[100][100];

int visited[100][100]={0};

int i,j;

for(i=0;i<n;i++){

for(j=0;j<n;j++){

scanf("%c",&ch[i][j]);

}

getchar();

}

for(i=0;i<n;i++){

for(j=0;j<n;j++){

dfs(ch,n,n,i,j);

}

}

for(i=0;i<n;i++){

for(j=0;j<n;j++){

printf("%c",ch[i][j]);

}

printf("\n");

}

return 0;

}

相关推荐
青桔柠薯片1 小时前
Linux软件编程:线程和进程间通信
linux·开发语言·线程·进程
foundbug9991 小时前
基于C# WinForm实现串口数据读取与实时折线图显示
开发语言·c#
im_AMBER1 小时前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
Polaris北1 小时前
第二十九天打卡
算法
CodeJourney_J2 小时前
从“Hello World“ 开始 C++
c语言·c++·学习
样例过了就是过了2 小时前
LeetCode热题100 环形链表 II
数据结构·算法·leetcode·链表
码农幻想梦2 小时前
3472. 八皇后(北京大学考研机试题目)
考研·算法·深度优先
匠心网络科技2 小时前
JavaScript进阶-ES6 带来的高效编程新体验
开发语言·前端·javascript·学习·面试
一只大袋鼠2 小时前
并发编程(三):线程快照统计・grep+awk+sort+uniq 实战详解
java·开发语言·多线程·并发编程