最小步数模型——AcWing 1107. 魔板

news2024/11/19 20:39:01

最小步数模型

定义

最小步数模型通常是指在某种约束条件下,寻找从初始状态到目标状态所需的最少操作或移动次数的问题。这类问题广泛存在于算法、图论、动态规划、组合优化等领域。具体来说,它涉及确定一个序列或路径,使得按照特定规则执行一系列步骤后,能够从起始位置或状态转换到目标位置或状态,且所花费的步骤尽可能少。

运用情况

  1. 图的最短路径问题:如Dijkstra算法、Floyd-Warshall算法等,用于寻找两点间经过边的最小权重和,即最少步数。
  2. 迷宫问题:寻找从起点到终点的最短路径,每步只能上下左右移动。
  3. 跳台阶问题:一个人可以1步或2步上楼梯,求n阶楼梯有多少种不同的上法,也是求最小步数的一个变体。
  4. 爬楼梯问题:每次可以爬1阶或2阶,求达到n阶楼梯的最少步数,考虑动态规划解法。
  5. 状态转换问题:如编辑距离(将一个字符串转换为另一个字符串最少的插入、删除、替换操作次数)。

注意事项

  1. 状态定义:明确问题中的状态如何表示,状态转移方程如何建立,这是解决问题的基础。
  2. 边界条件:正确设定初始状态和目标状态,以及任何可能的限制条件,避免无限循环或错误解。
  3. 避免重复计算:在动态规划等方法中,使用记忆化技术或递推公式减少重复子问题的计算。
  4. 最优子结构:利用问题的最优子结构,即问题的最优解可以由其子问题的最优解组合得到。
  5. 复杂度控制:考虑算法的时间和空间复杂度,选择合适的算法和数据结构以提高效率。

解题思路

  1. 分析问题:明确问题的输入、输出及约束条件,识别问题的类型(如是否为最短路径、最优化问题等)。
  2. 选择模型:根据问题特征选择合适的算法模型,如贪心、动态规划、图算法等。
  3. 状态定义与转移:定义状态表示问题的某一阶段,构建状态转移方程,描述如何从一个状态转移到另一个状态。
  4. 设计算法:依据状态转移方程设计算法,可能是递归、迭代、图的遍历等。
  5. 实现与优化:编写代码实现算法,考虑边界条件和特殊情况处理,优化算法以降低时间和空间复杂度。
  6. 验证与测试:通过测试用例验证算法的正确性,确保能正确处理各种边界条件和特殊情况。

AcWing 1107. 魔板

题目描述

AcWing 1107. 魔板 - AcWing

运行代码

#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <queue>

using namespace std;

char g[2][4];
unordered_map<string, pair<char, string>> pre;
unordered_map<string, int> dist;

void set(string state)
{
    for (int i = 0; i < 4; i ++ ) g[0][i] = state[i];
    for (int i = 7, j = 0; j < 4; i --, j ++ ) g[1][j] = state[i];
}

string get()
{
    string res;
    for (int i = 0; i < 4; i ++ ) res += g[0][i];
    for (int i = 3; i >= 0; i -- ) res += g[1][i];
    return res;
}

string move0(string state)
{
    set(state);
    for (int i = 0; i < 4; i ++ ) swap(g[0][i], g[1][i]);
    return get();
}

string move1(string state)
{
    set(state);
    int v0 = g[0][3], v1 = g[1][3];
    for (int i = 3; i > 0; i -- )
    {
        g[0][i] = g[0][i - 1];
        g[1][i] = g[1][i - 1];
    }
    g[0][0] = v0, g[1][0] = v1;
    return get();
}

string move2(string state)
{
    set(state);
    int v = g[0][1];
    g[0][1] = g[1][1];
    g[1][1] = g[1][2];
    g[1][2] = g[0][2];
    g[0][2] = v;
    return get();
}

int bfs(string start, string end)
{
    if (start == end) return 0;

    queue<string> q;
    q.push(start);
    dist[start] = 0;

    while (!q.empty())
    {
        auto t = q.front();
        q.pop();

        string m[3];
        m[0] = move0(t);
        m[1] = move1(t);
        m[2] = move2(t);

        for (int i = 0; i < 3; i ++ )
            if (!dist.count(m[i]))
            {
                dist[m[i]] = dist[t] + 1;
                pre[m[i]] = {'A' + i, t};
                q.push(m[i]);
                if (m[i] == end) return dist[end];
            }
    }

    return -1;
}

int main()
{
    int x;
    string start, end;
    for (int i = 0; i < 8; i ++ )
    {
        cin >> x;
        end += char(x + '0');
    }

    for (int i = 1; i <= 8; i ++ ) start += char('0' + i);

    int step = bfs(start, end);

    cout << step << endl;

    string res;
    while (end != start)
    {
        res += pre[end].first;
        end = pre[end].second;
    }

    reverse(res.begin(), res.end());

    if (step > 0) cout << res << endl;

    return 0;
}

代码思路

  1. 状态表示:用一个长度为8的字符串表示矩阵的状态,前四位表示第一行,后四位逆序表示第二行。
  2. 状态转换:定义了三种状态转换函数move0move1move2,分别对应三种操作。
  3. 广度优先搜索:使用BFS从初始状态开始搜索,利用一个队列来存储待探索的状态,一个哈希表dist记录每个状态到初始状态的最小步数,另一个哈希表pre记录每个状态的前驱状态和对应的操作。
  4. 路径回溯:当找到目标状态时,通过pre哈希表回溯并构造出从初始状态到目标状态的操作序列。

改进思路

  1. 减少空间消耗:使用迭代而非递归来保存路径,可以减少递归调用栈的空间消耗。
  2. 剪枝:在BFS过程中,可以添加剪枝策略,如遇到已经访问过且步数更优的状态时直接跳过,避免重复探索。
  3. 输入验证:在读取目标状态时增加输入验证,确保输入是合法的(例如,确保是0和1组成,且0和1的数量符合要求)。
  4. 优化状态表示:直接使用整型或位操作来表示状态,可能在某些情况下减少内存使用和加快状态比较速度。
  5. 清晰的函数命名和注释:增加函数和关键变量的注释,使代码更易于理解和维护。

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

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

相关文章

【JS】纯web端使用ffmpeg实现的视频编辑器-视频合并

纯前端实现的视频合并 接上篇ffmpeg文章 【JS】纯web端使用ffmpeg实现的视频编辑器 这次主要添加了一个函数&#xff0c;实现了视频合并的操作。 static mergeArgs(timelineList) {const cmd []console.log(时间轴数据,timelineList)console.log("文件1",this.readD…

BAS(入侵与攻击模拟)正在替代红队测试?

之前经常会被用户问到&#xff0c;漏扫、渗透和红队红的区别是啥&#xff1f; 传统的漏扫、渗透和红蓝对抗&#xff0c;可以看到工具化的漏洞不可靠&#xff0c;人工的成本就高。怎么找到一个漏洞可信度又高&#xff0c;成本又低的&#xff0c;就诞生了BAS。 抛开漏扫&#xf…

多商户b2b2c商城系统怎么运营

B2B2C多用户商城系统支持多种运营模式&#xff0c;以满足不同类型和发展阶段的企业需求。以下是五大主要的运营模式&#xff1a; **1. 自营模式&#xff1a;**平台企业通过建立自营线上商城&#xff0c;整合自身多渠道业务。通过会员、商品、订单、财务和仓储等多用户商城管理系…

windows自带的性能采集配置方法

1 计算机---右键---管理 2 性能--数据收集器几---用户自定义 3新建--输入程序名称 并在此页面选择--手动创建&#xff08;高级&#xff09; 4 下一步--勾选性能计数器---下一步 5 添加--找到process Processor Time User Time Handle Count ID Process Private Bytes…

Java8新特性之Optional、Lambda表达式、Stream、新日期Api使用总结

标题 Optional类常用Api使用说明Optional API 使用建议 Lambda表达式Lambda 表达式的局限性与解决方案 Stream案例实操优化 Stream 操作 新的日期和时间APILocalDateTime在SpringBoot中的应用 函数式接口&#xff08;Functional&#xff09; Optional博客参考地址1 Stream博客参…

核心实验:基于Web前端的性能测试分析!

实验简介 本实验主要利用IE和Chrome的F12开发人员工具结合Web前端测试分析相关知识&#xff0c;对常见网站进行基于前端的性能测试分析&#xff0c;本实验将不会使用到测试开发相关技术&#xff0c;而是纯粹意义上的手工测试&#xff0c;但却是很容易找到系统前端性能及设计问…

什么是继电器测试负载箱?

继电器测试负载箱专门用于测试继电器性能的设备&#xff0c;它能够模拟各种实际工况下的负载&#xff0c;以便对继电器进行全面、准确的性能评估。继电器是一种广泛应用于电力系统、自动化控制系统等领域的关键元件&#xff0c;其主要功能是在输入信号的控制下&#xff0c;实现…

耐克:老大的烦恼

股价暴跌20%&#xff0c;老大最近比较烦。 今天说说全球&#xff08;最&#xff09;大运动品牌——耐克。 最近耐克发布2023-2024财年业绩&#xff08;截止于2024.5.31&#xff09;&#xff0c;还是爆赚几百亿美元&#xff0c;还是行业第一&#xff0c;但业绩不及预期&#xf…

不同node版本的切换及其指定版本vue-cli脚手架下载

目录 一.清空本地已安装node.js版本 二.装nvm管理工具 三.安装指定node版本 四.使用nvm命令切换或删除指定node版本 五.在指定node版本下下载指定vue-cli脚手架 一.清空本地已安装node.js版本 1.按健winR弹出窗口&#xff0c;键盘输入cmd&#xff0c;然后敲回车。 2.输入…

对比学习,新的顶会神器!2024最新SOTA&应用盘点!

【对比学习&#xff0c;Contrastive Learning】是一种自监督学习方法&#xff0c;通过将视觉表示拉近相似样本、推远不相似样本来学习特征。它不依赖于标签&#xff0c;利用数据增强和负样本采样来提升特征的区分性。对比学习在提高模型对不同数据变化的鲁棒性方面表现出色&…

A股站不稳3000点让人稀罕不已啊

今天的A股&#xff0c;让人稀罕不已&#xff0c;你知道是为什么吗&#xff1f;盘面出现2个重要信号&#xff0c;一起来看看&#xff1a; 1、今天两市冲了下3000点&#xff0c;第一个主题炒作的热点终于出现了&#xff0c;税改方向的行情发酵&#xff0c;并带动着其他改革相关方…

Git 安装

Git 安装 在使用 Git 前我们需要先安装 Git。Git 目前支持 Linux/Unix、Solaris、Mac 和 Windows 平台上运行。Git 各平台安装包下载地址为&#xff1a;http://git-scm.com/downloads 在 Linux 平台上安装&#xff08;包管理工具安装&#xff09; 首先&#xff0c;你可以试着输…

Splashtop 致力于增强远程访问的安全性

数字时代&#xff0c;网络安全是企业运营的基石。随着远程工作模式的普及&#xff0c;企业越来越依赖远程访问解决方案。这既带来了灵活性和生产力的提升&#xff0c;也增加了安全风险。 最近接二连三发生的安全事件&#xff0c;凸显了强化安全措施的必要性。Splashtop 深知安…

Upload-Labs靶场闯关

文章目录 Pass-01Pass-02Pass-03Pass-04Pass-05Pass-06Pass-07Pass-08Pass-09Pass-10Pass-11Pass-12Pass-13Pass-14Pass-15Pass-16Pass-17Pass-18Pass-19Pass-20 以下是文件上传绕过的各种思路&#xff0c;不过是鄙人做题记下来的一些思路笔记罢了。 GitHub靶场环境下载&#x…

Mac|install vue

安装Node&#xff1a;Node.js — Download Node.js 选择系统为mac&#xff0c;安装步骤在终端输入 &#xff08;放文字版在这里&#xff5e;方便复制&#xff09; # installs nvm (Node Version Manager) curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/ins…

WebSocket解决方案(springboot 基于Redis发布订阅)

WebSocket 因为一般的请求都是HTTP请求&#xff08;单向通信&#xff09;&#xff0c;HTTP是一个短连接&#xff08;非持久化&#xff09;&#xff0c;且通信只能由客户端发起&#xff0c;HTTP协议做不到服务器主动向客户端推送消息。WebSocket确能很好的解决这个问题&…

【ARM系列】GIC600AE功能安全

GIC600AE在原GIC600版本基础上增加了FuSa功能&#xff0c;所增加的FuSa特性都集成在GIC600外围&#xff0c;不会改变原GIC600的功能。 GIC600AE主要安全机制分布图&#xff1a; GIC-600AE包含以下FuSa安全机制&#xff1a; lockstep logic protection 通过添加duplication l…

数值治理学习记录

添加链接描述 数值清洗规则 数据质量问题 数据治理校验规则 数据探查分析 数据质量规则指标 转自&#xff1a;公众号《数据治理体系》

嵌入式c语言1——gcc以及linux嵌入式

GCC全名GNU Complier Collection&#xff0c;是一个开源的程序语言解释器&#xff0c;运行在linux系统中 对以程序名后缀结尾源代码文件&#xff0c;gcc可以做解释并生成可执行文件

贪心算法算法,完全零基础小白教程,不是计算机的都能学会!超详解

目录 一、基本概念 二、举几个例子&#xff0c;便于理解 1、找零问题 2、最小路径和 3、背包问题 1&#xff09;只考虑体积的贪心策略&#xff1a; 2&#xff09; 只考虑价值的贪心策略&#xff1a; 三、贪心策略的特点 四、贪心策略证明 四、如何学习贪心 五、例题…