蓝桥杯备赛: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 导致只读取了部分地图。
相关推荐
十月的皮皮6 小时前
stm20260720-从新手 C 到量产 STM32 工程:程序设计推导指南
c语言·开发语言·stm32·stm32cubemx·hal库
Echo缘7 小时前
嵌入式系统C语言资源分类与内存分布分析
c语言·开发语言
胖大和尚7 小时前
C++ 多线程编程的实现方式
c++·thread
在水一缸8 小时前
深入浅出 Catch2:现代 C++ 测试框架的优雅实践
开发语言·c++·单元测试·log4j·测试框架·catch2
2401_841495648 小时前
【数据结构】B*树
数据结构·c++·b树·算法·删除·插入·三分分裂
斐夷所非8 小时前
在纷繁竞逐中稳步前行:C++ 2006–2020
c++
保持清醒5409 小时前
类和对象上
c++
乱七八糟的屋子9 小时前
Poco C++高级实战教程:线程池+日志系统+加密算法+WebSocket长连接
c++·websocket·加密解密·#poco·#c++高级开发
hold?fish:palm10 小时前
7 接雨水
开发语言·c++·leetcode
流浪00111 小时前
数据结构篇(五):线性表——栈
数据结构·c++·算法