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

最小步数模型

定义

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

运用情况

  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. 清晰的函数命名和注释:增加函数和关键变量的注释,使代码更易于理解和维护。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智能数字人直播带货软件源码系统 实现真人直播形象 带完整当然安装代码包以及搭建教程

系统概述 智能数字人直播带货软件源码系统&#xff0c;是一个集成了先进的人工智能、3D建模、语音合成、自然语言处理等技术于一体的创新平台。它旨在通过构建高度定制化的虚拟主播&#xff0c;为用户提供沉浸式、高效能的直播体验。与传统直播相比&#xff0c;该系统的核心优…

基于自回归超先验的有损图像压缩框架

文章信息 论文题目为《Joint Autoregressive and Hierarchical Priors for Learned Image Compression》&#xff0c;文章来自NIPS2018谷歌团队,是第一篇端到端图像压缩论文《variational image compression with a scale hyperprior》的改进版本&#xff0c;在《variational i…

Java 并发集合:CopyOnWrite 写时复制集合介绍

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 016 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…

【Qwen2部署实战】Qwen2初体验:用Transformers打造智能聊天机器人

系列篇章&#x1f4a5; No.文章1【Qwen部署实战】探索Qwen-7B-Chat&#xff1a;阿里云大型语言模型的对话实践2【Qwen2部署实战】Qwen2初体验&#xff1a;用Transformers打造智能聊天机器人3【Qwen2部署实战】探索Qwen2-7B&#xff1a;通过FastApi框架实现API的部署与调用4【Q…

IIC电平转换电路原理

一、电平转换的必要性 在IIC主从设备连接时&#xff0c;由于主从设备可能存在不同的电源电压&#xff08;如5V、3.3V、1.8V等&#xff09;&#xff0c;导致需要进行电平转换以确保正常通信。 二、电平转换电路的基本组成 电平转换电路通常包括上拉电阻、MOS管&#xff08;通常…

C++基础(二):C++入门(一)

C是在C的基础之上&#xff0c;容纳进去了面向对象编程思想&#xff0c;并增加了许多有用的库&#xff0c;以及编程范式 等。熟悉C语言之后&#xff0c;对C学习有一定的帮助&#xff0c;本篇博客主要目标&#xff1a; 1. 补充C语言语法的不足&#xff0c;以及C是如何对C语言设计…

AI与音乐:终极对决,机械混音师将扬弃人类知识!

AI与音乐 一. 引言1.1 AI在音乐创作中的应用1.2 AI在音乐表演与演奏中的应用 二. AI在音乐创作中的应用2.1 AI在音乐创作中的应用技术2.1.1 深度学习2.1.2 遗传算法2.1.3 神经网络 2.2 不同AI算法在音乐创作中的应用2.2.1 使用LSTM神经网络模型生成新的音乐2.2.2 使用基于模板的…

`THREE.LineBasicMaterial` 是 three.js 中用来创建用于绘制线条的基本材质。

demo案例 THREE.LineBasicMaterial 是 three.js 中用来创建用于绘制线条的基本材质。以下是它的入参、出参、方法和属性的详细说明。 入参 (Constructor Parameters) THREE.LineBasicMaterial 构造函数可以接收一个包含多个属性的对象。常用属性如下&#xff1a; const ma…

c++ 构造,析构,拷贝,移动构造函数

文章目录 概述1.构造函数2. 拷贝构造函数3.移动构造函数4.析构函数 例子QTUE4/5 c 小结 概述 对于c来说&#xff0c;最基础的是类。对于一个类来说&#xff0c;主要由以下函数构成。如下&#xff1a; 构造函数拷贝构造函数移动构造函数析构函数 当然&#xff0c;还有一个操作…

做测试/爬虫 selenium 元素定位 谷歌浏览器 插件推荐,提高元素定位效率

注:插件均在谷歌应用商店 下载 1.XPath Helper 插件 作用&#xff1a;用于Html中对目标字段或者属性值进行匹配 快捷启动&#xff1a;ctrl shift x 示例图如下&#xff1a; 2. ChroPath 插件 作用&#xff1a; 提高元素定位效率 启动&#xff1a;谷歌浏览器 按 F12 -&g…

Query Rewriting for Retrieval-Augmented Large Language Models

文章目录 题目摘要方法实验 题目 检索增强大语言模型的查询重写 论文地址&#xff1a;https://arxiv.org/abs/2305.14283 项目地址&#xff1a;https://github.com/xbmxb/RAG-query-rewriting 摘要 大语言模型&#xff08;LLM&#xff09;在检索--然后阅读&#xff08;retriev…

使用 Amazon Bedrock Converse API 简化大语言模型交互

本文将介绍如何使用 Amazon Bedrock 最新推出的 Converse API&#xff0c;来简化与各种大型语言模型的交互。该 API 提供了一致的接口&#xff0c;可以无缝调用各种大型模型&#xff0c;从而消除了需要自己编写复杂辅助功能函数的重复性工作。文中示例将展示它相比于以前针对每…

「ETL趋势」分区支持PostgreSQL、Greenplum、Gauss200, 定时任务支持Kettle

FineDataLink作为一款市场上的顶尖ETL工具&#xff0c;集实时数据同步、ELT/ETL数据处理、数据服务和系统管理于一体的数据集成工具&#xff0c;进行了新的维护迭代。本文把FDL4.1.9最新功能作了介绍&#xff0c;方便大家对比&#xff1a;&#xff08;产品更新详情&#xff1a;…

学习记录之数学表达式(6)

目录 十二、图与网络12.1 有向图12.2 元组与对象12.3 二元关系与有向图12.4 无向图12.5 有向网络12.6 作业 十三、树13.1 例子13.2 定义13.3 Java代码13.4 作业 十四、 m \mathbf{m} m叉树14.1 预备知识&#xff1a;字符串14.2 m \mathbf{m} m-叉树的定义14.3 Java代码14.4 作…

mysql-sql-第十三周

学习目标&#xff1a; sql 学习内容&#xff1a; 37.查询各科成绩最高分、最低分和平均分&#xff1a; 以如下形式显示&#xff1a;课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率 及格为>60,中等为&#xff1a;70-80,优良为&#xff1a;80-90,优秀…

2024 年江西省研究生数学建模竞赛A题:交通信号灯管理问题分析、实现代码及参考论文

2024 年江西省研究生数学建模竞赛题目交通信号灯管理 1 题目 交通信号灯是指挥车辆通行的重要标志&#xff0c;由红灯、绿灯、 黄灯组成。红灯停、绿灯行&#xff0c;而黄灯则起到警示作用。交通 信号灯分为机动车信号灯、非机动车信号灯、人行横道信号 灯、方向指示灯等。 一…

OpenSSH漏洞扫描(CVE-2024-6387、CVE-2006-5051、CVE-2008-4109)

目录 POC&#xff1a;ssh_poc.py 使用方法 github CVE-2024-6387 漏洞信息 补丁 POC&#xff1a;ssh_poc.py import sys import socket import argparse import threading import queue import os from datetime import datetime from urllib.parse import urlparse from…

LinuxRT启动Veristand项目的配置文件

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

FreeRTOS的任务理论

文章目录 2 FreeRTOS的任务理论2.1 任务及任务优先级2.2 任务状态理论2.2.1 任务状态的转换2.2.2 任务状态改变相关函数2.2.3 调度器相关函数 2.3 FreeRTOS延时2.3.1 vTaskDelay延时2.3.2 vTaskDelayUntil延时2.3.3 pdMS_TO_TICKS&#xff08;x&#xff09;宏 2.4 TCB任务控制块…

kafka 实现精确一次性语义实践总结

文章目录 前言幂等生产者幂等生产者的工作原理幂等生产者的局限性如何使用幂等生产者 事务事务的应用场景事务可以解决哪些问题事务是如何保证精确一次性的使用事物 API事物的工作原理 事务的性能 前言 Kafka的精确一次性语义与国际象棋正好相反&#xff1a;要理解它不容易&am…