蓝桥杯备赛: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 导致只读取了部分地图。
相关推荐
旖-旎4 小时前
分治(快速选择算法)(3)
c++·算法·leetcode·排序算法·快速选择
xiaoye-duck5 小时前
【C++:哈希表封装】哈希表封装 myunordered_map/myunordered_set 实战:底层原理 + 完整实现
数据结构·c++·散列表
A.A呐5 小时前
【C++第二十三章】C++11
开发语言·c++
亿秒签到6 小时前
L2-007 家庭房产
数据结构·c++·算法
jimy16 小时前
C语言函数指针
c语言·开发语言
2401_892070986 小时前
【Linux C++ 日志系统实战】日志消息对象 LogMessage 完整实现:流式拼装 + 标准化输出
linux·c++·日志系统·流式日志
paeamecium6 小时前
【PAT甲级真题】- Longest Symmetric String (25)
数据结构·c++·算法·pat考试
A.A呐7 小时前
【C++第二十二章】哈希与散列
c++·算法·哈希算法
眺望电子-ARM嵌入式7 小时前
RK3588 Type-C一线通,DP显示输出实战指南
c语言·开发语言
wangjialelele7 小时前
从磁盘查找理解 B 树 | B+树:原理、插入、分裂与性能分析
c语言·开发语言·数据结构·c++·b树