蓝桥杯备赛: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 导致只读取了部分地图。
相关推荐
WWJA王文举14 小时前
I²C通信完整流程详解:START、地址、ACK、数据、Repeated START和STOP一次讲透
c语言·开发语言
ShineWinsu16 小时前
对于C++:C++11中lambda、function、bind的解析
c++·面试·笔试·开发·lambda·bind·function
码匠许师傅16 小时前
【C++ 面试真题】聊聊 C++ 的拷贝构造与拷贝赋值
java·c++·面试
qq_4480111616 小时前
C语言中的动态内存分配
c语言·开发语言·php
动词ing17 小时前
【学习笔记】C语言(数组指针与指针数组+字符数组+函数+参数传递+字符串作为形参+递归函数+指针函数+回调函数+结构体嵌套+内存动态分配函数)
c语言·笔记·学习
旖旎夜光17 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
汉字萌萌哒17 小时前
2024CSP-J入门级C++真题详解
开发语言·c++
hy.z_77718 小时前
【C++】13. 继承
c++
汉字萌萌哒18 小时前
2019CCF-CSP入门级C++试题解析
java·开发语言·c++
小雨笙笙18 小时前
C语言:变量三属性——存储类型
c语言·开发语言