【洛谷P9303题解】AC- [CCC 2023 J5] CCC Word Hunt

在CCC单词搜索游戏中,单词隐藏在一个字母网格中。目标是确定给定单词在网格中隐藏的次数。单词可以以直线或直角的方式排列。以下是详细的解题思路及代码实现:

传送门: https://www.luogu.com.cn/problem/P9303

解题思路

  1. 输入读取与初始化

    • 读取要搜索的单词和网格的行数、列数。
    • 将网格存储为二维向量。
  2. 方向定义

    • 定义八个可能的搜索方向,包括上、右上、右、右下、下、左下、左、左上。
  3. 边界检查

    • 检查给定的坐标是否在网格范围内。
  4. 深度搜索

    • 从网格中每个与单词首字母匹配的位置开始,向八个方向进行深度搜索。
    • 在搜索过程中,可以继续沿当前方向或在未转过弯的情况下沿垂直方向继续搜索。
  5. 计数

    • 统计所有可能的单词匹配方式,并输出总的匹配次数。

代码实现

cpp 复制代码
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int r, c;
string word;
int length;
vector<vector<string>> graph;

// 定义八个可能的搜索方向
const int dx[8] = {-1,-1, 0, 1, 1, 1, 0,-1};
const int dy[8] = { 0, 1, 1, 1, 0,-1,-1,-1};

// 检查坐标是否在网格范围内
bool good(int x, int y) {
    return x >= 0 && x < r && y >= 0 && y < c;
}

// 深度搜索函数
int search(int x, int y, int cur, bool turned, int dirn) {
    if (cur == length - 1) return 1; // 找到完整匹配
    int cnt = 0;

    // 继续沿当前方向搜索
    int nx = x + dx[dirn], ny = y + dy[dirn];
    if (good(nx, ny) && graph[nx][ny] == string(1, word[cur + 1])) {
        cnt += search(nx, ny, cur + 1, turned, dirn);
    }

    // 如果未转过弯,尝试沿垂直方向搜索
    if (!turned) {
        int turnDirs[2] = {(dirn + 2) % 8, (dirn + 6) % 8}; // 计算垂直方向
        for (int k = 0; k < 2; ++k) {
            int newDir = turnDirs[k];
            int tx = x + dx[newDir], ty = y + dy[newDir];
            if (good(tx, ty) && graph[tx][ty] == string(1, word[cur + 1])) {
                cnt += search(tx, ty, cur + 1, true, newDir);
            }
        }
    }

    return cnt;
}

int main() {
    cin >> word;
    length = word.length();
    cin >> r >> c;

    // 初始化网格
    graph.resize(r, vector<string>(c));
    for (int i = 0; i < r; ++i)
        for (int j = 0; j < c; ++j)
            cin >> graph[i][j];

    int count = 0;

    // 遍历网格,寻找所有可能的起点
    for (int i = 0; i < r; ++i) {
        for (int j = 0; j < c; ++j) {
            if (graph[i][j] == string(1, word[0])) { // 找到单词首字母
                for (int k = 0; k < 8; ++k) { // 尝试所有方向
                    int ni = i + dx[k], nj = j + dy[k];
                    if (good(ni, nj) && graph[ni][nj] == string(1, word[1])) { // 确保第二字母匹配
                        count += search(ni, nj, 1, false, k); // 开始深度搜索
                    }
                }
            }
        }
    }

    cout << count << endl; // 输出结果
    return 0;
}

总结

以上代码实现了对字母网格中单词的搜索,能够处理单词以直线或直角方式排列的情况。通过深度搜索,代码能够有效地找出所有可能的匹配,并统计匹配次数。

相关推荐
水饺编程几秒前
第5章,[标签 Win32] :设备的尺寸(三)
c语言·c++·windows·visual studio
Cando学算法1 分钟前
中位数定理:到所有点的距离之和最小的点就是中位数
c++·算法·学习方法
nlpming3 分钟前
opencode 上下文压缩(Compaction)机制
算法
anew___5 分钟前
算法刷题避坑指南:从数据规模到易错点的实战总结
算法
HZY1618yzh11 分钟前
洛谷题解:P16304 [蓝桥杯 2026 省 Java C 组] 抽奖活动
java·c++·算法·蓝桥杯
智者知已应修善业24 分钟前
【51单片机从奇数始再转偶数逐一点亮并循环】2023-9-8
c++·经验分享·笔记·算法·51单片机
倔强的猴子(翻版)30 分钟前
我用 Python 写了个排序库,一亿数据量下比 C 级 np.sort() 快 7 倍
人工智能·python·算法·阿里云·文心一言
郝学胜-神的一滴31 分钟前
深入理解回归损失函数:MSE、L1 与 Smooth L1 的设计哲学
人工智能·python·程序人生·算法·机器学习·数据挖掘·回归
努力努力再努力wz32 分钟前
【MySQL进阶系列】拒绝冗余SQL:带你透彻理解视图的底层逻辑
android·c语言·数据结构·数据库·c++·sql·mysql
iCxhust1 小时前
在 emu8086 中可以直接编译运行的完整汇编程序,演示数组的定义、遍历、求和、求最大值。
开发语言·前端·javascript·汇编·单片机·嵌入式硬件·算法