蓝桥杯备赛:Day1-P1101 单词方阵

📚 算法笔记:P1101 单词方阵 (模拟与搜索)

1. 题目简述

单词方阵

在一个 N × N N \times N N×N 的字母方阵中找出所有的 yizhong。单词可以沿 8 个方向(上、下、左、右、左上、右上、左下、右下)直线延伸。不属于任何一个 yizhong 单词的字符需用 * 代替。

2. 核心代码 (C++ 实现)

C++ 复制代码
#include<bits/stdc++.h>
using namespace std;

// 全局变量:存起点坐标、地图、标记位
int Record[10005][2], cnt = 0; 
char Init[105][105];
bool mark[105][105]; 

// 核心工具:8方向偏移量数组
int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};
string target = "yizhong";
int n;

void Find() 
{
    for(int k = 1; k <= cnt; k++) 
    { // 遍历所有记录好的 'y'
        int r = Record[k][0];
        int c = Record[k][1];
        
        for (int i = 0; i < 8; i++) 
        { // 尝试8个方向
            bool flag = true;
            // 顺着当前方向检查接下来的6个字母(i,z,h,o,n,g)
            for (int step = 1; step <= 6; step++) 
            {
                int nr = r + dx[i] * step;
                int nc = c + dy[i] * step;
                
                // 边界判定 + 字符匹配判定
                if (nr < 1 || nr > n || nc < 1 || nc > n || Init[nr][nc] != target[step]) 
                {
                    flag = false;
                    break;
                }
            }
            // 如果整条线匹配成功,则标记(染色)
            if(flag) 
            {
                for(int step = 0; step <= 6; step++) 
                {
                    mark[r + dx[i] * step][c + dy[i] * step] = true;
                }
            }
        }
    }
}

int main() 
{
    ios::sync_with_stdio(0), cin.tie(0);
    
    cin >> n;
    for (int i = 1; i <= n; i++) 
    {
        for(int j = 1; j <= n; j++) 
        {
            cin >> Init[i][j];
            if(Init[i][j] == 'y') 
            { // 记录所有可能的起点
                cnt++;
                Record[cnt][0] = i;
                Record[cnt][1] = j;
            }
        }
    }
    
    Find();
    
    // 输出逻辑:根据标记位决定输出字符还是 '*'
    for (int i = 1; i <= n; i++) 
    {
        for (int j = 1; j <= n; j++) 
        {
            if (mark[i][j]) cout << Init[i][j];
            else cout << "*";
        }
        cout << "\n";
    }
    return 0;
}

3. 核心考点与注意事项

🔍 核心考点
  1. 方向数组 (Direction Array) :利用 dx[], dy[] 将 8 个方向的逻辑抽象化,避免冗长的 if-else 判断。
  2. 向量伸缩搜索 :通过 (r + dx[i]*step, c + dy[i]*step) 实现直线搜索,确保搜索不拐弯。
  3. 辅助标记数组 (Mark Array) :使用 bool mark[][] 记录结果。这是处理"先搜索、后处理"类题目的标准做法。
  4. 空间换时间 :预先存储 'y' 的坐标,避免对整个地图进行盲目搜索。
⚠️ 注意事项
  • 边界检查 :在访问数组下标前,必须判断 nrnc 是否在 1 ~ n 之间,防止内存越界。
  • 数据类型 :存储地图要用 char,比较字符要用单引号 'y'
  • 输入优化 :蓝桥杯数据量大时,记得加 ios::sync_with_stdio(0)

4. 易错点回顾 (My Mistakes)

  1. 方向数组索引对齐 :数组 dx[8] 的索引是 0~7,循环写成 1~8 会导致漏搜方向且越界。
  2. 直线逻辑缺失 :初期容易漏掉 step 偏移乘法,导致无法保持直线。
  3. 输入漏项 :在循环中误加 break 导致只读取了部分地图。
相关推荐
楼田莉子5 分钟前
CMake学习:动态库场景下的应用
c++·后端·学习·软件构建
jingshaoqi_ccc7 分钟前
使用QT6创建一个可编辑的表格并导出和载入
c++·qt·表格
天若有情67317 分钟前
C++进阶:普通重载运算符 vs 隐式类型转换重载运算符,一篇讲透区别
开发语言·c++·算法
流年如夢18 分钟前
文件读写操作与易错点总结
c语言
云深麋鹿25 分钟前
C++ | 二叉搜索树
开发语言·c++
永远睡不够的入28 分钟前
C++11新特性详解(上):从列表初始化到右值引用
开发语言·c++
c++圈来了个新人30 分钟前
C++类和对象(中)
c语言·开发语言·数据结构·c++·考研·算法
思麟呀32 分钟前
5种IO模型
linux·运维·服务器·c++
bucenggaibian33 分钟前
C语言如何直接控制硬件?指针、内存与寄存器
c语言·内存·指针·寄存器·硬件控制
2401_8920709833 分钟前
红黑树(RBTree):原理 + 5 大性质 + 旋转 + 插入 + 删除 + 完整工程级代码逐行解析
c语言·数据结构·红黑树