2024年蓝桥杯国赛A组题 九宫格全解析:基于BFS算法的代码实现与优化

深度学习
• 阅读 7

2024年蓝桥杯国赛A组题 九宫格全解析:基于BFS算法的代码实现与优化 蓝桥杯国赛 九宫格问题 BFS算法 代码解析 解题步骤 第1张 一、题目解读 2024年蓝桥杯国A的九宫格题目(对应洛谷P10578)要求通过旋转九宫格中的2x2区域,实现从初始状态到目标状态的转换,并计算最小步数。该问题属于经典的图论搜索问题,需要高效的状态转换与路径优化,考验算法设计与代码实现能力。

二、解题思路 采用广度优先搜索(BFS)为核心算法,通过以下关键点解决该问题:

1. 状态表示:将3x3矩阵转换为字符串,简化状态存储与比较。

2. 旋转操作:设计旋转函数,对指定2x2区域进行顺时针旋转,避免重复计算。

3. BFS搜索:利用队列存储状态,配合哈希表标记已访问状态,确保无重复遍历。

4. 目标判定:通过字符串比对快速判断是否达到目标状态,减少计算开销。

三、解题步骤

  1. 初始化与预处理:

    读取输入,将初始矩阵和目标矩阵(1-9顺序排列)转换为字符串形式。

    若初始状态即为目标,直接返回0步。

  2. BFS搜索流程:

    入队初始状态,标记为已访问。

    循环遍历队列:

     取出当前状态,尝试对所有可能的2x2区域(共4个)进行旋转。
    
     生成新状态并转换为字符串,若为目标状态则返回步数+1。
    
     若新状态未访问过,标记并加入队列,步数+1。
    
     若遍历结束未找到目标,返回-1(理论上所有状态可解)。
  3. 旋转优化:通过临时变量交换法实现顺时针旋转,避免复杂循环,提升效率。

四、代码与注释 C++ #include #include #include #include using namespace std;

// 将3x3矩阵转换为字符串表示 string gridToString(const vector<vector>& grid) { string s; for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) s += to_string(grid[i][j]); // 拼接数字为字符串 return s; }

// 旋转2x2区域的函数 vector<vector> rotate(const vector<vector>& grid, int x, int y) { vector<vector> newGrid = grid; // 顺时针旋转 int temp = newGrid[x][y]; newGrid[x][y] = newGrid[x+1][y]; newGrid[x+1][y] = newGrid[x+1][y+1]; newGrid[x+1][y+1] = newGrid[x][y+1]; newGrid[x][y+1] = temp; // 临时变量交换法 return newGrid; }

int bfs(const vector<vector>& start) { vector<vector> target = {{1,2,3},{4,5,6},{7,8,9}}; // 目标状态 string targetStr = gridToString(target); string startStr = gridToString(start);

if (startStr == targetStr) return 0; // 初始状态即目标

queue<pair<vector<vector<int>>, int>> q; // 队列存储状态与步数
unordered_map<string, bool> visited; // 标记已访问状态

q.push({start, 0});
visited[startStr] = true;

while (!q.empty()) {
    auto current = q.front().first;
    int steps = q.front().second;
    q.pop();

    // 尝试所有可能的2x2旋转区域
    for (int i = 0; i < 2; ++i) {
        for (int j = 0; j < 2; ++j) {
            vector<vector<int>> next = rotate(current, i, j); // 旋转生成新状态
            string nextStr = gridToString(next);

            if (nextStr == targetStr) return steps + 1; // 找到目标直接返回步数

            if (!visited[nextStr]) { // 未访问则入队
                visited[nextStr] = true;
                q.push({next, steps + 1});
            }
        }
    }
}
return -1; // 理论上所有状态都可解

}

int main() { ios::sync_with_stdio(false); cin.tie(nullptr); // 加快输入速度

int T;
cin >> T;
while (T--) {
    vector<vector<int>> grid(3, vector<int>(3));
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j)
            cin >> grid[i][j];

    cout << bfs(grid) << '\n';
}
return 0;

} 五、总结 该代码通过BFS算法与旋转优化,实现了九宫格问题的快速求解。关键在于状态转换的高效表示(矩阵转字符串)和避免重复搜索的哈希表标记。未来可进一步探索剪枝策略(如A*算法)或位运算优化状态存储,以降低空间复杂度。此外,旋转操作的巧妙实现为类似网格变换问题提供了参考思路。 参考:蓝桥杯国赛

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
2021美赛A题(真菌对木制分解效率的影响)——赛题解读&解题思路
2021美赛A题(真菌对木制分解效率的影响)——赛题解读&解题思路赛题目的一.多种真菌对枯枝落叶/木制纤维分解的影响模型二.真菌的相互作用关系模型三.大气变化对天气的影响模型四.物种在不同环境下的优劣势五.真菌多样性对系统分解凋落物效率的影响模型赛题目的赛题目的:探索真菌
Wesley13 Wesley13
3年前
CSS实现自适应九宫格布局 大全
看到微博和朋友圈都实现了图片九宫格,曾经有次面试也问到了九宫格这个问题,当时想到的是先固定每个单元格的宽高,然后进行浮动。今天想折腾一下,实现自适应父元素宽度的布局。这次我只写了四种方式去实现九宫格,算上inlineblock的话就是五种了。首先要注意的是九宫格容器是宽高相等的正方形,并且是自适应的,这里关键是实现宽高相等,有些人想到了相对视口宽度
Stella981 Stella981
3年前
2019全国大学生信息安全大赛两道web
简单小结菜鸟第一次打国赛,这次题目质量很高,学到了许多姿势。<!moreWebJustsoso打开题目,源代码出存在提示:!(https://0d077ef9e74d8.cdn.sohucs.com/romWP63_png)使用LFI读取index.php与hint.phph
可莉 可莉
3年前
2019全国大学生信息安全大赛两道web
简单小结菜鸟第一次打国赛,这次题目质量很高,学到了许多姿势。<!moreWebJustsoso打开题目,源代码出存在提示:!(https://0d077ef9e74d8.cdn.sohucs.com/romWP63_png)使用LFI读取index.php与hint.phph
贾蔷 贾蔷
1天前
【蓝桥杯2015省赛解析】生命之树(洛谷P8625):树形DP解题全攻略
一、题目解读“生命之树”是一道经典的树形结构问题,要求计算一棵带权树中,以某个节点为根的最大子树权值和。题目输入为n个节点及边信息,每个节点有权值wi,需找到所有节点中,子树权值和最大的节点,并输出其值。核心挑战在于如何处理树形结构的递归关系,并高效聚合子
深度学习 深度学习
1天前
2024蓝桥杯省赛B组前缀总分(洛谷P12124)解题思路与代码详解
一、题目解读2024年蓝桥杯省B组题目“前缀总分”(对应洛谷P12124)要求计算给定字符串集合中,所有前缀的最长公共前缀(LCP)的总分,并找出通过移动字符位置后可能获得的最大总分。题目考察字符串处理与动态规划能力,需高效计算LCP并优化得分策略。二、解
贾蔷 贾蔷
1天前
2023年GESP六级题解:洛谷P10108闯关游戏动态规划解法详解
一、题目解读本文针对2023年GESP六级题目“闯关游戏”(洛谷P10108)进行详细解析。题目要求玩家通过不同关卡路径选择,计算从起点到终点的最大得分。关卡间存在跳跃规则,需结合动态规划思想设计高效算法,最终输出最优得分。二、解题思路采用动态规划(Dyn
贾蔷 贾蔷
2星期前
蓝桥杯2023接龙数列(洛谷P9242)题解:动态规划与数字首尾匹配的完美应用
一、题目解读这道蓝桥杯省赛真题要求找出数字序列中最长的接龙子序列(每个数字的首位等于前一个数字的末位),并计算需要删除的最少数字个数。题目考察动态规划的实际应用能力,是理解数字特征处理和状态转移的典型案例。二、解题步骤1.处理n1的特殊边界情况2.读取输入
贾蔷 贾蔷
2星期前
2013 蓝桥杯 省赛B组 翻硬币(洛谷P8597题) 从暴力BFS到贪心算法的优化之路
一、问题背景与理解洛谷P8597是一道经典的翻硬币问题,题目描述如下:给定两个由''和'o'组成的字符串s1和s2,分别表示初始状态和目标状态。每次操作可以选择任意位置开始翻转连续的k个硬币(''变'o','o'变'')。要求计算出从初始状态变为目标状态所
贾蔷 贾蔷
1天前
牛客12576题全解析:动态规划+质因数分解解决跳跃问题
一、题目解读牛客12576题是一道经典的算法题,要求给定起点N和终点M,求解从N到M的最少跳跃次数。题目考察的核心在于路径优化与动态规划思想,需结合数论中的质因数分解技巧,通过合理设计算法降低时间复杂度,避免暴力枚举的指数级耗时。二、解题思路采用“动态规划