c/c++藍橋杯經典編程題100道(19)漢諾塔問題

漢諾塔問題

->返回c/c++藍橋杯經典編程題100道-目錄


目錄

漢諾塔問題

一、題型解釋

二、例題問題描述

三、C語言實現

解法1:遞歸法(難度★)

解法2:迭代法(難度★★★)

四、C++實現

解法1:遞歸法(使用STL容器記錄步驟,難度★☆)

解法2:面向對象封裝(難度★★)

五、總結對比表

六、特殊方法與內置函數補充

1. C語言中的結構體棧

2. C++的?std::vector

3. 漢諾塔數學公式


一、題型解釋

漢諾塔(Tower of Hanoi)是經典的遞歸問題,描述如下:

  • 三根柱子:A(起點)、B(輔助)、C(終點)。

  • 若干盤子:初始時所有盤子按大小順序疊放在A柱,大的在下,小的在上。

  • 目標:將所有盤子從A柱移動到C柱,每次只能移動一個盤子,且任何時候大盤子不能放在小盤子上

常見題型:

  1. 基礎問題:計算移動步驟或最少步數(n個盤子需移動?2^n - 1?次)。

  2. 多柱擴展:四根或多根柱子的變種問題(如Frame-Stewart算法)。

  3. 路徑限制:限制某些移動規則(如只能從A→B、B→C、C→A)。


二、例題問題描述

例題1:輸入盤子數?n=3,輸出移動步驟:

A → C  
A → B  
C → B  
A → C  
B → A  
B → C  
A → C

例題2:輸入?n=4,輸出最少移動次數?15
例題3:驗證移動序列?[A→B, A→C, B→C]?是否是?n=2?的有效解(輸出?true)。


三、C語言實現

解法1:遞歸法(難度★)

通俗解釋

  • 將問題分解為三步:

    1. 將前?n-1?個盤子從A移動到B(借助C)。

    2. 將第?n?個盤子從A移動到C。

    3. 將?n-1?個盤子從B移動到C(借助A)。

c

#include <stdio.h>// 遞歸函數:將n個盤子從src移動到dst,使用aux作為輔助
void hanoi(int n, char src, char aux, char dst) {if (n == 1) { // 基線條件:只剩一個盤子直接移動printf("%c → %c\n", src, dst);return;}hanoi(n - 1, src, dst, aux); // 將n-1個盤子從src移動到aux(借助dst)printf("%c → %c\n", src, dst); // 移動第n個盤子到dsthanoi(n - 1, aux, src, dst); // 將n-1個盤子從aux移動到dst(借助src)
}int main() {int n = 3;hanoi(n, 'A', 'B', 'C');return 0;
}

代碼邏輯

  1. 基線條件:當?n=1?時,直接移動盤子。

  2. 遞歸分解

    • 第一步:將?n-1?個盤子從起點移動到輔助柱(遞歸調用)。

    • 第二步:移動最大的盤子到目標柱。

    • 第三步:將?n-1?個盤子從輔助柱移動到目標柱(遞歸調用)。

  3. 時間復雜度:O(2^n),因為每一步分解為兩個子問題。


解法2:迭代法(難度★★★)

通俗解釋

  • 用棧模擬遞歸過程,手動管理每一步的狀態(當前盤子數、源柱、輔助柱、目標柱)。

c

#include <stdio.h>
#include <stdlib.h>// 定義棧結構體,存儲每一步的狀態
typedef struct {int n;char src, aux, dst;
} StackFrame;void hanoiIterative(int n, char src, char aux, char dst) {StackFrame stack[100]; // 假設n不超過100層int top = -1; // 棧頂指針// 初始狀態:移動n個盤子從src到dst,使用aux輔助StackFrame init = {n, src, aux, dst};stack[++top] = init;while (top >= 0) {StackFrame current = stack[top--]; // 彈出當前任務if (current.n == 1) {printf("%c → %c\n", current.src, current.dst);} else {// 分解為三個子任務(注意順序與遞歸相反)// 子任務3:移動n-1個盤子從aux到dst,使用src輔助StackFrame task3 = {current.n - 1, current.aux, current.src, current.dst};stack[++top] = task3;// 子任務2:移動第n個盤子從src到dstStackFrame task2 = {1, current.src, current.aux, current.dst};stack[++top] = task2;// 子任務1:移動n-1個盤子從src到aux,使用dst輔助StackFrame task1 = {current.n - 1, current.src, current.dst, current.aux};stack[++top] = task1;}}
}int main() {hanoiIterative(3, 'A', 'B', 'C');return 0;
}

代碼邏輯

  1. 棧模擬遞歸:顯式管理待處理的任務(類似遞歸調用棧)。

  2. 任務分解順序:由于棧是后進先出,子任務需按相反順序入棧。

  3. 優勢:避免遞歸的棧溢出風險,適合大規模n。


四、C++實現

解法1:遞歸法(使用STL容器記錄步驟,難度★☆)

通俗解釋

  • 使用?vector?存儲移動步驟,方便后續處理或輸出。

cpp

#include <iostream>
#include <vector>
using namespace std;vector<string> steps; // 存儲移動步驟void hanoi(int n, char src, char aux, char dst) {if (n == 1) {steps.push_back(string(1, src) + " → " + dst);return;}hanoi(n - 1, src, dst, aux);steps.push_back(string(1, src) + " → " + dst);hanoi(n - 1, aux, src, dst);
}int main() {hanoi(3, 'A', 'B', 'C');for (const string& step : steps) {cout << step << endl;}return 0;
}

代碼邏輯

  • 與C語言遞歸邏輯相同,但使用?vector<string>?動態存儲步驟。

  • 輸出靈活性:可隨時訪問或修改步驟記錄。


解法2:面向對象封裝(難度★★)

通俗解釋

  • 將漢諾塔問題封裝為類,支持多種操作(如統計步數、驗證步驟)。

cpp

#include <iostream>
#include <vector>
using namespace std;class HanoiSolver {
private:vector<string> steps;void move(int n, char src, char aux, char dst) {if (n == 1) {steps.push_back(string(1, src) + " → " + dst);return;}move(n - 1, src, dst, aux);steps.push_back(string(1, src) + " → " + dst);move(n - 1, aux, src, dst);}
public:void solve(int n) {steps.clear();move(n, 'A', 'B', 'C');}void printSteps() {for (const string& step : steps) {cout << step << endl;}}
};int main() {HanoiSolver solver;solver.solve(3);solver.printSteps();return 0;
}

代碼邏輯

  1. 封裝性:將步驟記錄和求解邏輯封裝在類中。

  2. 擴展性:可添加方法統計步數、驗證移動序列等。


五、總結對比表

方法時間復雜度空間復雜度優點缺點
遞歸法O(2^n)O(n)代碼簡潔,易理解棧溢出風險
迭代法O(2^n)O(n)避免遞歸棧溢出代碼復雜,需手動管理棧
STL容器記錄O(2^n)O(2^n)靈活處理步驟內存占用高
面向對象封裝O(2^n)O(2^n)擴展性強,易于維護代碼稍長

六、特殊方法與內置函數補充

1. C語言中的結構體棧

  • 作用:手動實現棧結構,存儲遞歸狀態(需注意棧大小限制)。

2. C++的?std::vector

  • 動態數組:自動擴展容量,適合存儲不定長的移動步驟。

3. 漢諾塔數學公式

  • 最少步數2^n - 1,可通過位運算快速計算(如?(1 << n) - 1)。

->返回c/c++藍橋杯經典編程題100道-目錄

?

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

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

相關文章

趕AI大潮:在VSCode中使用DeepSeek及近百種模型的極簡方法

1 趕AI大潮&#xff1a;在VSCode中使用DeepSeek及近百種模型的極簡方法 1.1 背景 DeepSeek在春節期間突然大行其道&#xff0c;欣喜國力大增的同時&#xff0c;對于普通IT工作者&#xff0c;如何才能享受這一波AI紅利&#xff0c;讓自己的工作更出彩呢&#xff1f; ??很多人…

【一文讀懂】HTTP與Websocket協議

HTTP協議 概述 HTTP (Hypertext Transfer Protocol)&#xff0c;即超文本傳輸協議&#xff0c;是一種用于在客戶端和服務器之間傳輸超文本&#xff08;例如網頁、圖片、音頻、視頻等&#xff09;的通信協議。它是萬維網&#xff08;WWW&#xff09;的基礎&#xff0c;負責在瀏…

IDEA集成DeepSeek

引言 隨著數據量的爆炸式增長&#xff0c;傳統搜索技術已無法滿足用戶對精準、高效搜索的需求。 DeepSeek作為新一代智能搜索技術&#xff0c;憑借其強大的語義理解與深度學習能力&#xff0c;正在改變搜索領域的游戲規則。 對于 Java 開發者而言&#xff0c;將 DeepSeek 集成…

從零開始部署DeepSeek:基于Ollama+Flask的本地化AI對話系統

從零開始部署DeepSeek&#xff1a;基于OllamaFlask的本地化AI對話系統 一、部署背景與工具選型 在AI大模型遍地開花的2025年&#xff0c;DeepSeek R1憑借其出色的推理能力和開源特性成為開發者首選。本文將以零基礎視角&#xff0c;通過以下工具鏈實現本地化部署&#xff1a; …

圖論入門算法:拓撲排序(C++)

上文中我們了解了圖的遍歷(DFS/BFS), 本節我們來學習拓撲排序. 在圖論中, 拓撲排序(Topological Sorting)是對一個有向無環圖(Directed Acyclic Graph, DAG)的所有頂點進行排序的一種算法, 使得如果存在一條從頂點 u 到頂點 v 的有向邊 (u, v) , 那么在排序后的序列中, u 一定…

第1章大型互聯網公司的基礎架構——1.2 客戶端連接機房的技術1:DNS

客戶端啟動時要做的第一件事情就是通過互聯網與機房建立連接&#xff0c;然后用戶才可以在客戶端與后臺服務器進行網絡通信。目前在計算機網絡中應用較為廣泛的網絡通信協議是TCP/IP&#xff0c;它的通信基礎是IP地址&#xff0c;因為IP地址有如下兩個主要功能。 標識設備&…

全面解析鴻蒙(HarmonyOS)開發:從入門到實戰,構建萬物互聯新時代

文章目錄 引言 一、鴻蒙操作系統概述二、鴻蒙開發環境搭建三、鴻蒙核心開發技術1. **ArkUI框架**2. **分布式能力開發**3. **原子化服務與元服務** 四、實戰案例&#xff1a;構建分布式音樂播放器五、鴻蒙開發工具與調試技巧六、鴻蒙生態與未來展望結語 引言 隨著萬物互聯時代…

Android:播放Rtsp視頻流的兩種方式

一.SurfaceView Mediaplayer XML中添加SurfaceView: <SurfaceViewandroid:id"id/surface_view"android:layout_width"match_parent"android:layout_height"match_parent"/> Activity代碼&#xff1a; package com.android.rtsp;impor…

Next.js【詳解】CSS 樣式方案

全局樣式 Global CSS 默認已創建&#xff0c;即 src\app\globals.css&#xff0c;可根據需要修改 默認在全局布局中導入 src\app\layout.tsx import "./globals.css";組件樣式 CSS Modules 新建文件 src\app\test\styles.module.css .red {color: red;}導入目標頁面…

LVS相關原理

一、LVS集群的體系結構 1.1 LVS簡介 LVS 是 Linux Virtual Server 的簡稱&#xff0c;也就是 Linux 虛擬服務器 , 是一個由章文嵩博士發起的自由軟件項目&#xff0c;它的官方站點是 www.linuxvirtualserver.org 。現在 LVS 已經是 Linux標準內核的一部分&#xff0c;在Linux2…

【2025深度學習系列專欄大綱:深入探索與實踐深度學習】

第一部分:深度學習基礎篇 第1章:深度學習概覽 1.1 深度學習的歷史背景與發展軌跡 1.2 深度學習與機器學習、傳統人工智能的區別與聯系 1.3 深度學習的核心組件與概念解析 神經網絡基礎 激活函數的作用與類型 損失函數與優化算法的選擇 1.4 深度學習框架簡介與選擇建議 第2…

Java與C語言中取模運算符%的區別對比

博客主頁&#xff1a; [小????????] 本文專欄: Java 文章目錄 &#x1f4af;前言&#x1f4af;C語言中的取模運算符 %基本行為示例 注意事項示例&#xff1a;負數取模 &#x1f4af;Java中的取模運算符 %基本行為示例 對浮點數的支持示例&#xff1a;浮點數取模 符…

OpenCV機器學習(4)k-近鄰算法(k-Nearest Neighbors, KNN)cv::ml::KNearest類

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 cv::ml::KNearest 是 OpenCV 機器學習模塊中的一部分&#xff0c;它提供了實現 k-近鄰算法&#xff08;k-Nearest Neighbors, KNN&#xff09;的…

過于依賴chatgpt編程會有哪些弊端?

過于依賴ChatGPT編程可能會帶來以下問題&#xff1a; 1. 基礎不扎實&#xff0c;容易“變菜” 以前遇到代碼還會琢磨哪里不懂、怎么改&#xff0c;現在直接復制粘貼&#xff0c;時間長了可能連基本的語法和邏輯都搞不清楚。就像考試總抄答案&#xff0c;真讓你自己寫的時候腦子…

紅隊視角出發的k8s敏感信息收集——Kubernetes API 擴展與未授權訪問

針對 Kubernetes 第三方組件與 Operator 的詳細攻擊視角分析&#xff0c;涵蓋 Service Mesh、Helm Releases 和 Database Operators 的潛在風險及利用方法。 攻擊鏈示例 1. 攻擊者通過未授權的 Tiller 服務部署惡意 Helm Chart → 2. 創建后門 Pod 并橫向移動至 Istio 控制平…

3D與2D機器視覺機械臂引導的區別

3D與2D機器視覺在機械臂引導中的主要區別如下&#xff1a; 數據維度 2D視覺&#xff1a;僅處理平面圖像&#xff0c;提供X、Y坐標信息&#xff0c;無法獲取深度&#xff08;Z軸&#xff09;數據。 3D視覺&#xff1a;處理三維空間數據&#xff0c;提供X、Y、Z坐標及物體的姿態…

日常開發中,使用JSON.stringify來實現深拷貝的坑

使用JSON.stringify的方式來實現深拷貝的弊端 弊端一&#xff1a;無法拷貝NaN、Infinity、undefined這類值 無法拷貝成功的原因&#xff1a; 對于JSON來說&#xff0c;它支持的數據類型只有null、string、number、boolean、Object、Array&#xff0c;所以對于它不支持的數據類…

AI大模型(如GPT、BERT等)可以通過自然語言處理(NLP)和機器學習技術,顯著提升測試效率

在軟件測試中,AI大模型(如GPT、BERT等)可以通過自然語言處理(NLP)和機器學習技術,顯著提升測試效率。以下是幾個具體的應用場景及對應的代碼實現示例: 1. 自動生成測試用例 AI大模型可以根據需求文檔或用戶故事自動生成測試用例。 代碼示例(使用 OpenAI GPT API): …

【Linux】Ubuntu Linux 系統——Node.js 開發環境

??大家好&#xff0c;我是練小杰&#xff0c;今天星期五了&#xff0c;同時也是2025年的情人節&#xff0c;今晚又是一個人的舉個爪子&#xff01;&#xff01; &#x1f642; 本文是有關Linux 操作系統中 Node.js 開發環境基礎知識&#xff0c;后續我將添加更多相關知識噢&a…

Dockerfile 編寫推薦

一、導讀 本文主要介紹在編寫 docker 鏡像的時候一些需要注意的事項和推薦的做法。 雖然 Dockerfile 簡化了鏡像構建的過程&#xff0c;并且把這個過程可以進行版本控制&#xff0c;但是不正當的 Dockerfile 使用也會導致很多問題。 docker 鏡像太大。如果你經常使用鏡像或者…