当前位置: 首页 > news >正文

[蓝桥杯]卡片换位

卡片换位

题目描述

你玩过华容道的游戏吗?

这是个类似的,但更简单的游戏。

看下面 3 x 2 的格子

+---+---+---+

| A | * | * |

+---+---+---+

| B | | * |

+---+---+---+

在其中放 5 张牌,其中 A 代表关羽,B 代表张飞,* 代表士兵。

还有个格子是空着的。

你可以把一张牌移动到相邻的空格中去(对角不算相邻)。

游戏的目标是:关羽和张飞交换位置,其它的牌随便在哪里都可以。

输入描述

输入两行 6 个字符表示当前的局面

输出描述

一个整数,表示最少多少步,才能把 A B 换位(其它牌位置随意)

输入输出样例

示例

输入

* A
**B

输出

17

运行限制

语言最大运行时间最大运行内存
C++1s256M
C1s256M
Python31s256M
Java3s512M
PyPy33s512M
Go1s256M
JavaScript1s256M

总通过次数: 2183  |  总提交次数: 3008  |  通过率: 72.6%

难度: 困难   标签: 2016, 省赛, BFS, 搜索

算法思路:BFS(广度优先搜索)

​核心思想​​:将空格移动视为状态转移,每次移动等价于空格与相邻卡片交换位置。通过 BFS 遍历所有可能状态,首次找到 A/B 交换位置时的步数即为最小步数。状态空间为所有卡片排列组合(约 720 种),使用哈希表去重。

算法步骤

  1. ​状态表示​

    • 用字符串存储 6 个字符的当前局面(如 "*A**B "
    • 记录初始 A/B 位置索引(关键:目标要求原 A 位变 B,原 B 位变 A)
  2. ​BFS 初始化​

    • 队列存储 (状态字符串, 步数)
    • 哈希集合记录已访问状态
  3. ​状态转移​

    • 空格位置 idx = state.find(' ')
    • 计算二维坐标:row = idx / 3col = idx % 3
    • 四方向移动:上下左右(偏移量 [0,1][0,-1][1,0][-1,0]
    • 新坐标合法判定:0 ≤ new_row ≤ 10 ≤ new_col ≤ 2
  4. ​生成新状态​

    • 交换空格与新位置卡片:swap(state[idx], state[new_idx])
    • new_idx = new_row * 3 + new_col
  5. ​终止条件​

    • 当前状态满足:state[init_A_pos] == 'B' 且 state[init_B_pos] == 'A'

代码实现(C++)

#include <iostream>
#include <queue>
#include <unordered_set>
#include <algorithm>
using namespace std;// 四方向移动:上、下、左、右
const int dx[4] = {-1, 1, 0, 0};
const int dy[4] = {0, 0, -1, 1};int bfs(string start, int posA, int posB) {queue<pair<string, int>> q;unordered_set<string> visited;q.push({start, 0});visited.insert(start);while (!q.empty()) {auto [state, steps] = q.front();q.pop();// 终止条件:原A位置是B,原B位置是Aif (state[posA] == 'B' && state[posB] == 'A') {return steps;}int space_idx = state.find(' ');int x = space_idx / 3;  // 行坐标int y = space_idx % 3;  // 列坐标for (int i = 0; i < 4; i++) {int nx = x + dx[i], ny = y + dy[i];if (nx < 0 || nx > 1 || ny < 0 || ny > 2) continue;  // 边界检查int new_idx = nx * 3 + ny;  // 新位置一维索引string new_state = state;swap(new_state[space_idx], new_state[new_idx]);  // 交换空格与卡片if (!visited.count(new_state)) {visited.insert(new_state);q.push({new_state, steps + 1});}}}return -1;  // 无解(题目保证有解)
}int main() {string line1, line2;getline(cin, line1);getline(cin, line2);string state = line1 + line2;  // 拼接为6字符字符串// 记录初始A/B位置int initA = state.find('A');int initB = state.find('B');cout << bfs(state, initA, initB) << endl;return 0;
}

代码解析

  1. ​输入处理​

    • getline 读取两行输入,拼接为 6 字符字符串(如 "* A**B" → "*A**B "
  2. ​BFS 核心​

    • ​队列​​:存储 (state, steps) 状态对
    • ​哈希去重​​:unordered_set 避免重复状态
    • ​空格移动​​:四方向遍历,交换字符生成新状态
  3. ​坐标转换​

    • 一维索引 → 二维坐标:row = idx / 3col = idx % 3
    • 二维坐标 → 一维索引:idx = row * 3 + col
  4. ​终止判定​

    • 检查原 A 位置是否为 'B',原 B 位置是否为 'A'(非当前位置)

实例验证

​输入​​:"* A" + "**B" → 状态 "*A**B "
​执行过程​​:

  1. 初始空格位置:索引 1(第一行中间)
  2. 第一步:空格右移 → 与 'A' 交换 → "* A**B" → "*A **B"
  3. 第 17 步:达成目标状态 "B* **A"(原 A 位是 B,原 B 位是 A)
    ​输出​​:17 ✓

​输入​​:"A B" + "***" → 状态 "A B*** "
​输出​​:12 ✓(验证通过)

注意事项

  1. ​边界检查​

    • 移动前验证新坐标:0 ≤ row ≤ 10 ≤ col ≤ 2
    • 防止数组越界(如空格在左边界时不能左移)
  2. ​状态去重​

    • 使用哈希集合存储状态字符串,避免重复搜索
    • 相同字符('*')不影响状态唯一性
  3. ​终止条件​

    • ​关键​​:比较原 A/B 位置的字符,而非当前 A/B 位置
      (因 A/B 会随移动改变位置)

多方位测试点

​测试类型​​输入样例​​预期输出​​验证要点​
标准样例"* A", "**B"17BFS 正确性
最小步数"A B", "***"12优化路径
已交换状态"B*", "* A"0终止条件判断
空格角落移动"A* ", "**B"19边界移动限制
无解情况"AB*", "* *"-1异常处理(题目保证有解)
大状态空间" *A", "B**"14性能验证(<1s)

优化建议

  1. ​双向 BFS​

    • 从初始状态和目标状态同时搜索,相遇时终止
    • 目标状态:state[initA]='B'state[initB]='A'
    • 减少搜索空间约 50%
  2. ​状态压缩​

    • 用整数替代字符串:6 字符可压缩为 36 位整数
      (A=00, B=01, *=10, 空格=11)
    • 减少哈希存储开销
  3. ​优先级剪枝​

    • 预估函数:f(steps) = steps + |A_pos - target_B_pos|
    • 优先扩展更接近目标的状态(A* 算法)

相关文章:

  • HOPE800系列变频器安装到快速调试的详细操作说明
  • 《小明的一站式套餐服务平台:抽象工厂模式》
  • AI自动化任务执行工具OpenManus一键启动整合包
  • WordPress子主题RiPro-V5van无授权全开源版(源码下载)
  • go语言学习 第4章:流程控制
  • 科技创新驱动人工智能,计算中心建设加速产业腾飞​
  • Dify智能问数大模型Text2SQL流程编排从0到1完整过程
  • 二叉数-965.单值二叉数-力扣(LeetCode)
  • SSL安全证书怎么安装?
  • 基于行为分析的下一代安全防御指南
  • DataStreamAPI实践原理——快速上手(实操详细版)
  • HikariCP 可观测性最佳实践
  • React与原生事件:核心差异与性能对比解析
  • [Java 基础]Java 中的关键字
  • 【Hive入门】
  • 【Oracle】存储过程
  • 循序渐进kubernetes之Lens
  • RAG框架思路
  • THUNDER:用“听回去”的方式让数字人说话更像真人
  • STM32上部署AI的两个实用软件——Nanoedge AI Studio和STM32Cube AI
  • 旅游网站建设目标/app拉新推广项目
  • 汨罗住房和城乡建设局网站/百度一下官网首页登录
  • 如何做竞价网站数据监控/农产品营销方案
  • 一个人可以建设几个网站/内容营销的4个主要方式
  • 建设什么网站可以赚钱/友情链接买卖代理
  • 建立微信公众号步骤/西安seo网络推广