[蓝桥杯]卡片换位

news2025/6/6 19:22:33

卡片换位

题目描述

你玩过华容道的游戏吗?

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

看下面 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位置是A
        if (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* 算法)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2399334.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【论文笔记】High-Resolution Representations for Labeling Pixels and Regions

【题目】&#xff1a;High-Resolution Representations for Labeling Pixels and Regions 【引用格式】&#xff1a;Sun K, Zhao Y, Jiang B, et al. High-resolution representations for labeling pixels and regions[J]. arXiv preprint arXiv:1904.04514, 2019. 【网址】…

【题解-洛谷】P9422 [蓝桥杯 2023 国 B] 合并数列

题目&#xff1a;P9422 [蓝桥杯 2023 国 B] 合并数列 题目描述 小明发现有很多方案可以把一个很大的正整数拆成若干正整数的和。他采取了其中两种方案&#xff0c;分别将他们列为两个数组 { a 1 , a 2 , ⋯ a n } \{a_1, a_2, \cdots a_n\} {a1​,a2​,⋯an​} 和 { b 1 , …

109页PPT华为流程模块L1-L4级梳理及研发采购服务资产5级建模

华为的流程体系是其核心竞争力之一&#xff0c;也是其从一家小型民营企业成长为全球领先科技巨头的重要支撑。这套体系的核心思想是以客户为中心、以价值创造为导向、以流程驱动业务、持续优化改进。 下载资料请查看文章中图片右下角信息 以下是华为流程体系的关键组成部分和特…

第N1周:one-hot编码案例

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客 &#x1f356; 原作者&#xff1a;K同学啊 一、one-hot编码概念 自然语言处理&#xff08;NLP&#xff09;中的文本数字化&#xff1a;文字对于计算机来说就仅仅只是一个个符号&#xff0c;计算…

Windows安装docker desktop

Windows 版本&#xff1a; Windows 10/11&#xff08;64位&#xff09;专业版、企业版或教育版&#xff08;家庭版需手动配置&#xff09;。 版本号需 ≥ 1909&#xff08;建议更新到最新系统&#xff09; 打开程序 启动服务后点点点 重启生效&#xff08;没有的话 安装WSL…

Ros(俩不同包的节点 交流 topic message)

不同的俩节点 如chao_node 和ma_node .在俩不同的包下。 他们若想互相产生联系&#xff0c; 就需要靠这个关系了。 想象一下是开黑的场景 其实群名就是topic 而发送的消息就是Message。 其中主动刷屏的message的一方 就是 Publisher 而接受的那一方 就是subsciber

李沐《动手学深度学习》 | 数值稳定性

文章目录 数值稳定性梯度消失Sigmoid作为激活函数 梯度爆炸 让训练更加稳定合理的权重初始化Xavier初始化&#xff08;常用&#xff09;He初始化/Kaiming方法 Batch Normalization Q&A 数值稳定性 当神经网络的深度比较深时&#xff0c;非常容易数值不稳定。 不稳定梯度是…

OpenCV CUDA模块图像处理------图像连通域标记接口函数connectedComponents()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数在 GPU 上执行二值图像的连通域标记操作&#xff0c;即将图像中所有相连的前景像素区域赋予相同的标签&#xff08;label&#xff09;&…

Android Studio 打包时遇到了签名报错问题:Invalid keystore format

错误指出密钥库的格式无效&#xff0c;可能是由于密钥库本身的问题导致的&#xff0c;还有一种可能是由于jdk版本导致。我试过重新签名&#xff0c;也是不行&#xff0c;后来发现是JDK版本问题&#xff0c;我的Studio之前是jbr11&#xff0c;好像后来合并代码重新下载编译了项目…

内存管理【Linux操作系统】

文章目录 简单谈一下物理内存管理页框为什么要把物理内存划分成一个一个固定大小的页框使用&#xff1f;对页框进行描述对页框进行组织管理虚拟地址→物理地址&#xff08;真实的页表&#xff09;真实的页表那我们如何把虚拟地址→物理地址呢&#xff1f;页表懒加载时&#xff…

Go语言学习-->从零开始搭建环境

Go语言学习–>从零开始搭建环境 1 开发环境 Go官网下载地址&#xff1a;https://golang.org/dl/ Go官方镜像站&#xff08;推荐&#xff09;&#xff1a;https://golang.google.cn/dl/ windos 平台下载&#xff1a; 我这里下载1.22稳定版 双击下载好的.msi文件 修改安装…

【力扣】3403. 从盒子中找出字典序最大的字符串 I

解法一&#xff1a; class Solution {public String answerString(String word, int numFriends) {//对字符的划分&#xff0c;word长度为n&#xff0c;共有n1个位置可以插入&#xff0c;但是要求被分为非空字符串&#xff0c;所以插入的位置最多为n-1。int n word.length();…

【前端】Vue3+elementui+ts,给标签设置样式属性style时,提示type check failed for prop,再次请出DeepSeek来解答

&#x1f339;欢迎来到《小5讲堂》&#x1f339; &#x1f339;这是《前端》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。&#x1f339; &#x1f339;温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01;&…

PyTorch——优化器(9)

优化器根据梯度调整参数&#xff0c;以达到降低误差 import torch.optim import torchvision from torch import nn from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear from torch.utils.data import DataLoader# 加载CIFAR10测试数据集&#xff0c;设置tr…

07 APP 自动化- appium+pytest+allure框架封装

文章目录 一、PO二、代码简单实现项目框架预览&#xff1a;base_page.pydir_config.pyget_data.pylogger.pystart_session.pyconfig.yamlkey_code.yamllaunch_page_loc.pylogin_page_loc.pylaunch_page.pylogin_page.pytest_login.pypytest.inirun.py 一、PO PO 分为四层 &…

英国2025年战略防御评估报告:网络与电磁域成现代战争核心

英国 2025 年战略防御评估 (SDR) 详细制定了一项计划&#xff0c;通过加强使用网络、人工智能和数字战争来整合其军事防御和进攻能力。 与美国一样&#xff0c;英国也被认为&#xff08;尽管未被公开证实&#xff09;会开展进攻性网络行动&#xff0c;甚至针对盟友。斯诺登泄露…

基于QPSK调制解调+Polar编译码(SCL译码)的matlab性能仿真,并对比BPSK

目录 1.引言 2.算法仿真效果演示 3.数据集格式或算法参数简介 4.MATLAB核心程序 5.算法涉及理论知识概要 6.参考文献 7.完整算法代码文件获得 1.引言 Polar码由土耳其教授Erdal Arikan于2008年提出&#xff0c;是第一种被严格证明可以达到香农极限的构造性编码方法。其核…

Glide NoResultEncoderAvailableException异常解决

首先将解决方法提出来&#xff1a;缓存策略DiskCacheStrategy.DATA。 使用Glide加载图片&#xff0c;版本是4.15.0&#xff0c;有天发现无法显示gif图片&#xff0c;原始代码如下&#xff1a; Glide.with(context).load(本地资源路径).diskCacheStrategy(DiskCacheStrategy.A…

无人机巡检智能边缘计算终端技术方案‌‌——基于EFISH-SCB-RK3588工控机/SAIL-RK3588核心板的国产化替代方案‌

一、方案核心价值‌ ‌实时AI处理‌&#xff1a;6TOPS NPU实现无人机影像的实时缺陷检测&#xff08;延迟&#xff1c;50ms&#xff09;‌全国产化‌&#xff1a;芯片、操作系统、算法工具链100%自主可控‌极端环境适配‌&#xff1a;-40℃~85℃稳定运行&#xff0c;IP65防护等…

相机--相机成像原理和基础概念

教程 成像原理 基础概念 焦距&#xff08;物理焦距&#xff09; 镜头的光学中心到感光元件之间的距离&#xff0c;用f表示&#xff0c;单位&#xff1a;mm&#xff1b;。 像素焦距 相机内参矩阵中的 fx​ 和 fy​ 是将物理焦距转换到像素坐标系的产物&#xff0c;可能不同。…