最小步數模型——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. 清晰的函數命名和注釋:增加函數和關鍵變量的注釋,使代碼更易于理解和維護。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/39348.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/39348.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/39348.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

jenkins在使用pipeline時,為何沒有方塊形視圖

項目場景&#xff1a; 安裝完Jenkins時后&#xff0c;通過pipeline創建的項目任務。 問題描述 在立即構建后&#xff0c;沒有顯示每個階段的視圖。 原因分析&#xff1a; 原因是&#xff0c;剛安裝的Jenkins&#xff0c;這個視圖不是Jenkins自帶的功能&#xff0c;而必須安裝…

《5小時吃透小red書》讀書筆記之打造爆款筆記原理

1.流量推送邏輯&#xff1a; 一篇筆記發布并審核后&#xff0c;平臺根據內容提取關鍵詞&#xff0c;開始小范圍發布測試&#xff1b;初次先分發到1000個興趣用戶&#xff0c;根據這1000個用戶等反饋決定是否給該筆記更多流量和推薦&#xff1b;考核標準是點擊率、完播率、互動…

高校實訓室:老年實訓室的教學案例

本文以高校老年實訓室為研究對象&#xff0c;通過詳細分析具體的教學案例&#xff0c;探討了老年實訓室在提升學生專業素養和實踐能力方面的重要作用。文中介紹了多個具有代表性的教學案例&#xff0c;包括健康評估、康復護理和心理關懷等方面&#xff0c;闡述了其教學目標、實…

EDA 虛擬機 Synopsys Sentaurus TCAD 2017.09 下載

下載地址&#xff08;制作不易&#xff0c;下載使用需付費&#xff0c;不能接受的請勿下載&#xff09;&#xff1a; 鏈接&#xff1a;https://pan.baidu.com/s/1327I58gvV1usWSqSrG7KXw?pwdo03i 提取碼&#xff1a;o03i

Boss直聘,無良廠商,亂封號

耽誤招工作&#xff0c;瞎吉兒封號 哥們單身 需要女生多的公司 問一下都不行&#xff0c;什么尿性 直接就給你封了 裝什么呢 辣雞boss 倒閉吧趕緊 我是狗子&#xff0c;希望你倒閉&#xff01;

枚舉類示例

package net.cnki.editor.costcenter.pojo.enums;import lombok.Getter;import java.util.Arrays;/*** 費用枚舉接口*/ public interface CosttypeEnumInterface {/*** 費用類型和費用信息-> 費用性質, 支付人 , 收取人, 費用信息狀態*/Getterenum CosttypePayerAndReceiveE…

使用PHP實現Web爬蟲

web爬蟲是一種自動化工具&#xff0c;可以瀏覽互聯網上的網頁&#xff0c;收集信息并存儲在一個數據庫中。在今天的大數據時代&#xff0c;web爬蟲越來越重要&#xff0c;因為它可以查找大量信息并進行數據分析。在本文中&#xff0c;我們將學習如何使用php編寫web爬蟲&#xf…

Radxa 學習摘錄

文章目錄 1、參考資料2、硬件知識CIF 和 ISP 3、shell4、交叉編譯工具鏈5、問題6、DTS7、驅動 1、參考資料 技術論壇&#xff08;推薦&#xff09; 官方資料下載 wiki資料 u-boot 文檔 u-boot 源碼 內核文檔 內核源碼 原理圖 radxa-repo radxa-build radxa-pkg radxa-doc…

尋找最適合你的交易風格

與Eagle Trader一起&#xff0c;您將擁有一位堅不可摧的合作伙伴&#xff0c;為您的交易之路增添堅實信心&#xff0c;并重塑交易體驗的每一個細節。我們量身定制的交易環境&#xff0c;更能讓您精準捕捉并駕馭符合您獨特交易風格的卓越條件&#xff0c;讓交易之旅更加自由暢快…

Python容器 之 字典--定義

1.字典的介紹 1, 字典 dict, 使用 {} 表示 2, 字典是由鍵(key)值(value)對組成的, key: value 3, 一個鍵值對是一組數據, 多個鍵值對之間使用 逗號隔開 4, 在一個字典中, 字典的鍵 是不能重復的&#xff0c;如果重復原數據會被覆蓋 5, 字典中的鍵 主要使用 字符串類型, 可以是…

Mac可以卸載掉系統自帶的軟件嗎 Mac第三方軟件無法卸載是為什么

在使用Mac電腦時&#xff0c;有時候我們會發現系統預裝的一些應用并不常用或者不符合個人需求&#xff0c;想要將它們卸載掉。然而&#xff0c;對于系統自帶的軟件&#xff0c;卸載并不簡單&#xff0c;需要謹慎對待以免影響系統穩定性和功能正常運行。下面我們來看看Mac可以卸…

Firefox 編譯指南2024 Windows10-使用Git 管理您的Firefox(五)

1. 引言 在現代軟件開發中&#xff0c;版本控制系統&#xff08;VCS&#xff09;是不可或缺的工具&#xff0c;它不僅幫助開發者有效管理代碼的變化&#xff0c;還支持團隊協作與項目管理。Mercurial 是一個高效且易用的分布式版本控制系統&#xff0c;其設計目標是簡潔、快速…

Linux CentOS Python 離線安裝 pip 使用.whl文件離線安裝

1、系統版本 cat /etc/redhat-release #查看系統版本命令 輸出&#xff1a;CentOS Linux release 7.9.2009 (Core) 2、在pip 官方網站 下載.whl文件&#xff1a;pip-24.1.1-py3-none-any.whl 3、安裝 python -m pip install pip-24.1.1-py3-none-any.whl 3、安裝之后運行…

Windows使用-設置虛擬內存及注意事項

文章目錄 前言一、設置虛擬內存打開“系統屬性”對話框在“系統屬性”對話框設置虛擬內存二、虛擬內存設置引發問題C盤空間不足桌面引用程序無法正常使用總結前言 虛擬內存是操作系統為應用程序提供的一種內存管理機制,最早是用于解決物理內存不足而影響操作系統運行效率問題…

【antd + vue】表格行合并,同時使用插槽

一、需求說明 表格中&#xff0c;如果一個學校有多個考試科目&#xff0c;則分行展示&#xff0c;其余列&#xff0c;則合并為一行展示&#xff0c;如圖所示 二、需求分析 1、表格行合并 相當于有4行&#xff0c;其中1、2行是同一個學校包含不同考試科目及對應人次的數據&am…

判斷磁盤是SSD或HDD盤

1. 判斷磁盤是SSD或HDD盤 1、沒有使用raid方案 lsblk -d -o name,rota命令&#xff0c;0表示SSD&#xff0c;1表示HDD # lsblk -d -o name,rota NAME ROTA sda 0 sdb 1 sdc 12、使用raid方案 下載工具 wget https://raw.githubusercontent.com/eLvErDe/hwraid…

Java_多線程:實現多線程

Java中實現多線程的常用方式&#xff1a; 繼承Thread類實現Runnable接口實現Callable接口(JDK>1.5)線程池方式創建 實現Runnable接口與Callable接口的區別 Callable規定&#xff08;重寫&#xff09;的方法是call()&#xff0c;Runnable規定&#xff08;重寫&#xff09;的…

Java的全局異常處理代碼

第一步&#xff1a;先寫一個異常管理類: package com.example.firefighting.exceptions;import com.example.firefighting.utils.Result; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerA…

手機數據恢復篇:如何在恢復出廠設置后的 iPhone 恢復短信

您可能會認為&#xff0c;在恢復出廠設置iPhone后恢復短信時&#xff0c;一切都會丟失&#xff0c;但是仍然有一些方法可以檢索您的重要對話。截至 2024 年&#xff0c;數據恢復技術的進步使得從備份甚至直接從設備內存中搶救消息變得更加容易。無論是通過 iCloud、iTunes 還是…

LeetCode Hard|124.二叉樹中的最大路徑和

力扣題目鏈接 題目解讀&#xff1a; 二叉樹路徑的定義即從1.任意節點出發&#xff0c;到達任意節點&#xff1b;2.該路徑至少包含一個節點&#xff0c;且不一定經過跟節點&#xff1b;3.求所有可能路徑和的最大值。 也就是說路徑途徑一個節點只能選擇來去兩個方向 考慮一個二叉…