C++中漢諾塔問題的示例分析

這篇文章將為大家詳細(xì)講解有關(guān)C++中漢諾塔問題的示例分析,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

10年的東川網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。全網(wǎng)整合營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整東川建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“東川網(wǎng)站設(shè)計(jì)”,“東川網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

漢諾塔問題,是心理學(xué)實(shí)驗(yàn)研究常用的任務(wù)之一。當(dāng)然我們是學(xué)計(jì)算機(jī)的,因此我們嘗試用計(jì)算機(jī)去求解它。

例題

openjudge6261 漢諾塔問題

描述

有一種智力玩具,在一塊銅板上有三根桿,最左邊的桿上自上而下、由小到大順序串著由n個(gè)圓盤構(gòu)成的塔。目的是將最左邊桿上的盤全部移到中間的桿上,條件是一次只能移動(dòng)一個(gè)盤,且不允許大盤放在小盤的上面。這就是著名的漢諾塔問題。

假定圓盤從小到大編號(hào)為1,2,3,……

輸入

輸入為一個(gè)整數(shù)后面跟三個(gè)單字符字符串。

整數(shù)為盤子的數(shù)目,后三個(gè)字符表示三個(gè)桿子的編號(hào)。

輸出

輸出每一步移動(dòng)盤子的記錄。一次移動(dòng)一行。

每次移動(dòng)的記錄為例如 a->3->b 的形式,即把編號(hào)為3的盤子從a桿移至b桿。

樣例輸入

2 a b c

樣例輸出

a->1->c
a->2->b
c->1->b

漢諾塔問題

漢諾塔問題的解決算法是一種經(jīng)典的分治算法,而分治算法最重要的三個(gè)步驟:

  1. 分解:如果說我們要將num個(gè)盤子從原柱子l通過過渡柱子mid移動(dòng)到目標(biāo)柱子r,那么我們可以先把上面的(num - 1)個(gè)盤子從原柱子l移動(dòng)到過渡柱子mid,之后再把編號(hào)num的這個(gè)盤子移動(dòng)到目標(biāo)柱子r上,最后再把那(num - 1)個(gè)盤子從過渡柱子mid移動(dòng)到目標(biāo)柱子r,就成功了。

  2. 解決:用遞歸分別再去解決子問題并輸出。(邊界條件:當(dāng)只有一個(gè)盤子既num == 1時(shí),直接輸出就好了)。

  3. 合并:遞歸回來的就是結(jié)果了,不用再合并。

簡(jiǎn)而言之,就是每次我們把第num個(gè)盤子單獨(dú)看成一個(gè)整體,剩下(num - 1)個(gè)盤子看成一個(gè)整體,之后對(duì)這兩個(gè)整體分別去進(jìn)行移動(dòng),使其到達(dá)目標(biāo)位置。

最后算一下時(shí)間復(fù)雜度,這里稍微有些難算。

假設(shè)i個(gè)盤子從一根柱子移動(dòng)到另一根柱子需要step(i)步

對(duì)于一個(gè)單獨(dú)的塔,程序會(huì)進(jìn)行以下操作:

  1. 將上面的(n - 1)個(gè)盤子移動(dòng)到過渡柱子,次數(shù)為step(n - 1)。

  2. 將第n個(gè)盤子移動(dòng)到目標(biāo)柱子,次數(shù)為1。

  3. 將過渡柱子上的(n - 1)個(gè)盤子移動(dòng)到目標(biāo)柱子,次數(shù)為step(n - 1)。

則可以得到遞推式

step(n) = 2 * step(n - 1) + 1

之后不停地遞推下去,就會(huì)得到

step(n) = 2^n * step(0) + 2^(n - 1) + 2^(n - 2) + ...... + 2^1 + 2^0

又因?yàn)?個(gè)盤子根本不用移,所以step(0) = 0

所以step(n) = 2^(n - 1) + 2^(n - 2) + ...... + 2^1 + 2^0

之后用等比數(shù)列的公式就可以推出:step(n) = 2^n^ - 1

我們發(fā)現(xiàn)移動(dòng)次數(shù)為2^n^ - 1,實(shí)際上這也是漢諾塔問題最少的移動(dòng)次數(shù)。所以最后得出解決漢諾塔問題的算法時(shí)間復(fù)雜度為O(2^n^)。

代碼

# include <cstdio>
# include <iostream> 
# include <cmath>
# include <cstring>
# include <algorithm>

using namespace std;

int n;
char a, b, c;

// hanoi(num, l, mid, r)表示需要將num個(gè)盤子從柱子l通過柱子mid移動(dòng)到柱子r。
void hanoi(int num, char l, char mid, char r)
{
  if (num == 1) printf("%c->%d->%c\n", l, num, r);
  else {
    hanoi(num - 1, l, r, mid);
    printf("%c->%d->%c\n", l, num, r);
    hanoi(num - 1, mid, l, r);
  }
}

int main()
{
  scanf("%d", &n);
  cin >> a >> b >> c;
  hanoi(n, a, c, b); // 這里因?yàn)轭}目中是讓所有盤子從左面的柱子移動(dòng)到中間的柱子,既從a到b。
  return 0;
}

就是小編整理的全部相關(guān)知識(shí)點(diǎn),感謝大家的學(xué)習(xí)和對(duì)創(chuàng)新互聯(lián)的支持。

關(guān)于“C++中漢諾塔問題的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

分享文章:C++中漢諾塔問題的示例分析
文章網(wǎng)址:http://muchs.cn/article22/jchojc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、網(wǎng)站內(nèi)鏈響應(yīng)式網(wǎng)站、App設(shè)計(jì)虛擬主機(jī)、定制開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)