• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            /*
            問(wèn)題描述:有三個(gè)柱子A, B, C. A柱子上疊放有n個(gè)盤(pán)子,每個(gè)盤(pán)子都比它下面的盤(pán)子要小一點(diǎn),
            可以從上到下用1, 2, ..., n編號(hào)。要求借助柱子B,把柱子A上的所有的盤(pán)子移動(dòng)到柱子C上。
            移動(dòng)條件為:1、一次只能移一個(gè)盤(pán)子;
            2、移動(dòng)過(guò)程中大盤(pán)子不能放在小盤(pán)子上,只能小盤(pán)子放在大盤(pán)子上。
            */
            /*
            遞歸的算法相信大多數(shù)人都知道,非遞歸算法也有出現(xiàn)過(guò)。
            如:摘自http://www.programfan.com/club/old_showbbs.asp?id=96548
            作者:qq590240
            #include <iostream>
            #include <stdlib.h>

            #ifdef _WIN32
            using namespace std;
            #endif

            static void hanoi(int height)
            {
            ??? int fromPole, toPole, Disk;
            ??? int *BitStr = new int[height],
            ??????? *Hold?? = new int[height];
            ??? char Place[]? = {'A', 'B', 'C'};
            ??? int i, j, temp;

            ??? for (i=0; i < height; i++)
            ??? {
            ??????? BitStr[i] = 0;
            ??????? Hold[i] = 1;
            ??? }
            ??? temp = 3 - (height % 2);
            ??? int TotalMoves = (1 << height) - 1;
            ??? for (i=1; i <= TotalMoves; i++)
            ??? {
            ??????? for (j=0 ; BitStr[j] != 0; j++)
            ??????? {
            ??????????? BitStr[j] = 0;
            ??????? }
            ??????? BitStr[j] = 1;
            ??????? Disk = j+1;
            ??????? if (Disk == 1)
            ??????? {
            ??????????? fromPole = Hold[0];
            ??????????? toPole = 6 - fromPole - temp;
            ??????????? temp = fromPole;
            ??????? }
            ??????? else
            ??????? {
            ??????????? fromPole = Hold[Disk-1];
            ??????????? toPole = 6 - Hold[0] - Hold[Disk-1];
            ??????? }
            ??????? cout << "Move disk " << Disk << " from " << Place[fromPole-1]
            ???????????? << " to " << Place[toPole-1] << endl;
            ??????? Hold[Disk-1] = toPole;
            ??? }
            }

            ?


            int main(int argc, char *argv[])
            {
            ??? cout << "Towers of Hanoi: " << endl
            ???????? << "moving a tower of n disks from pole A to pole B by using pole C" << endl;
            ??? cout << "Input the height of the original tower: ";
            ??? int height;
            ??? cin >> height;
            ??? hanoi(height);

            ??? system("PAUSE");
            ??? return EXIT_SUCCESS;
            }
            ?////////////////////////////////////////////////////////////
            ?我在這里根據(jù)《數(shù)學(xué)營(yíng)養(yǎng)菜》(談祥柏 著)提供的一種方法,編了一個(gè)程序來(lái)實(shí)現(xiàn)。
            */
            /*
            算法介紹:
            首先容易證明,當(dāng)盤(pán)子的個(gè)數(shù)為n時(shí),移動(dòng)的次數(shù)應(yīng)等于2^n - 1。
            一位美國(guó)學(xué)者發(fā)現(xiàn)一種出人意料的方法,只要輪流進(jìn)行兩步操作就可以了。
            首先把三根柱子按順序排成品字型,把所有的圓盤(pán)按從大到小的順序放在柱子A上。
            根據(jù)圓盤(pán)的數(shù)量確定柱子的排放順序:若n為偶數(shù),按順時(shí)針?lè)较蛞来螖[放 A B C;
            若n為奇數(shù),按順時(shí)針?lè)较蛞来螖[放 A C B。
            (1)按順時(shí)針?lè)较虬褕A盤(pán)1從現(xiàn)在的柱子移動(dòng)到下一根柱子,即當(dāng)n為偶數(shù)時(shí),若圓盤(pán)1在柱子A,則把它移動(dòng)到B;
            若圓盤(pán)1在柱子B,則把它移動(dòng)到C;若圓盤(pán)1在柱子C,則把它移動(dòng)到A。
            (2)接著,把另外兩根柱子上可以移動(dòng)的圓盤(pán)移動(dòng)到新的柱子上。
            即把非空柱子上的圓盤(pán)移動(dòng)到空柱子上,當(dāng)兩根柱子都非空時(shí),移動(dòng)較小的圓盤(pán)
            這一步?jīng)]有明確規(guī)定移動(dòng)哪個(gè)圓盤(pán),你可能以為會(huì)有多種可能性,其實(shí)不然,可實(shí)施的行動(dòng)是唯一的。
            (3)反復(fù)進(jìn)行(1)(2)操作,最后就能按規(guī)定完成漢諾塔的移動(dòng)。
            */
            #include <iostream>
            using namespace std;

            const int MAX = 64; //圓盤(pán)的個(gè)數(shù)最多為64

            struct st{? //用來(lái)表示每根柱子的信息
            ????? int s[MAX]; //柱子上的圓盤(pán)存儲(chǔ)情況
            ????? int top; //棧頂,用來(lái)最上面的圓盤(pán)
            ????? char name; //柱子的名字,可以是A,B,C中的一個(gè)
            ?????
            ????? int Top()//取棧頂元素
            ????? {
            ??????????? return s[top];
            ????? }
            ????? int Pop()//出棧
            ????? {
            ??????????? return s[top--];
            ????? }
            ????? void Push(int x)//入棧
            ????? {
            ??????????? s[++top] = x;
            ????? }
            } ;

            long Pow(int x, int y); //計(jì)算x^y
            void Creat(st ta[], int n); //給結(jié)構(gòu)數(shù)組設(shè)置初值
            void Hannuota(st ta[], long max); //移動(dòng)漢諾塔的主要函數(shù)

            int main(void)
            {
            ????? int n;
            ????? cin >> n; //輸入圓盤(pán)的個(gè)數(shù)
            ?????
            ????? st ta[3]; //三根柱子的信息用結(jié)構(gòu)數(shù)組存儲(chǔ)
            ????? Creat(ta, n); //給結(jié)構(gòu)數(shù)組設(shè)置初值

            ????? long max = Pow(2, n) - 1;//動(dòng)的次數(shù)應(yīng)等于2^n - 1
            ????? Hannuota(ta, max);//移動(dòng)漢諾塔的主要函數(shù)

            ????? system("pause");
            ????? return 0;
            }

            void Creat(st ta[], int n)
            {
            ????? ta[0].name = 'A';
            ????? ta[0].top = n-1;
            ????? for (int i=0; i<n; i++) //把所有的圓盤(pán)按從大到小的順序放在柱子A上
            ??????????? ta[0].s[i] = n - i;
            ???????????
            ????? ta[1].top = ta[2].top = 0;//柱子B,C上開(kāi)始沒(méi)有沒(méi)有圓盤(pán)
            ????? for (int i=0; i<n; i++)
            ??????????? ta[1].s[i] = ta[2].s[i] = 0;
            ???????????
            ????? if (n%2 == 0) //若n為偶數(shù),按順時(shí)針?lè)较蛞来螖[放 A B C
            ????? {
            ??????????? ta[1].name = 'B';
            ??????????? ta[2].name = 'C';
            ????? }
            ????? else? //若n為奇數(shù),按順時(shí)針?lè)较蛞来螖[放 A C B
            ????? {
            ??????????? ta[1].name = 'C';
            ??????????? ta[2].name = 'B';
            ????? }
            }

            long Pow(int x, int y)
            {
            ????? long sum = 1;
            ????? for (int i=0; i<y; i++)
            ??????????? sum *= x;

            ????? return sum;
            }

            void Hannuota(st ta[], long max)
            {
            ????? int k = 0; //累計(jì)移動(dòng)的次數(shù)
            ????? int i = 0;
            ????? int ch;
            ????? while (k < max)
            ????? {
            ??????????? //按順時(shí)針?lè)较虬褕A盤(pán)1從現(xiàn)在的柱子移動(dòng)到下一根柱子
            ??????????? ch = ta[i%3].Pop();
            ??????????? ta[(i+1)%3].Push(ch);
            ??????????? cout << ++k << ": " << "Move disk " << ch << " from " << ta[i%3].name << " to " << ta[(i+1)%3].name << endl;
            ??????????? i++;
            ??????????? //把另外兩根柱子上可以移動(dòng)的圓盤(pán)移動(dòng)到新的柱子上
            ??????????? if (k < max)
            ??????????? {???? //把非空柱子上的圓盤(pán)移動(dòng)到空柱子上,當(dāng)兩根柱子都為空時(shí),移動(dòng)較小的圓盤(pán)
            ????????????????? if (ta[(i+1)%3].Top() == 0 || ta[(i-1)%3].Top() > 0 && ta[(i+1)%3].Top() > ta[(i-1)%3].Top())
            ????????????????? {
            ??????????????????????? ch =? ta[(i-1)%3].Pop();
            ??????????????????????? ta[(i+1)%3].Push(ch);
            ??????????????????????? cout << ++k << ": " << "Move disk " << ch << " from " << ta[(i-1)%3].name << " to " << ta[(i+1)%3].name << endl;
            ????????????????? }
            ????????????????? else
            ????????????????? {
            ??????????????????????? ch =? ta[(i+1)%3].Pop();
            ??????????????????????? ta[(i-1)%3].Push(ch);
            ??????????????????????? cout << ++k << ": " << "Move disk " << ch << " from " << ta[(i+1)%3].name << " to " << ta[(i-1)%3].name << endl;
            ????????????????? }
            ??????????? }
            ????? }
            }

            ?

            Posted on 2006-06-07 18:00 夢(mèng)想飛揚(yáng) 閱讀(6600) 評(píng)論(4)  編輯 收藏 引用

            Feedback

            # re: 漢諾塔非遞歸算法  回復(fù)  更多評(píng)論   

            2006-06-11 18:31 by glacjay
            嗯,以前在哪本數(shù)學(xué)書(shū)上看到過(guò)。

            # re: 漢諾塔非遞歸算法  回復(fù)  更多評(píng)論   

            2006-06-12 11:00 by Jacky
            更正一下,在移動(dòng)步驟(2)中,應(yīng)該是當(dāng)兩個(gè)柱子都非空的時(shí)候才移動(dòng)較小的圓盤(pán)。

            # re: 漢諾塔非遞歸算法  回復(fù)  更多評(píng)論   

            2007-09-20 15:06 by mfkxowvfp
            能給出具體的理論驗(yàn)證嗎?

            # re: 漢諾塔非遞歸算法  回復(fù)  更多評(píng)論   

            2007-11-07 12:45 by 壽桃用戶入境
            疆景頗產(chǎn)

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            国产精品美女久久久久av爽| 色欲综合久久躁天天躁| 精品无码久久久久国产动漫3d| 99久久做夜夜爱天天做精品| 婷婷五月深深久久精品| 亚洲国产精品久久久久| 久久综合九色欧美综合狠狠| 欧洲精品久久久av无码电影| 欧美亚洲国产精品久久蜜芽| 国产精品久久久久久久app| 精品一区二区久久| 久久国产亚洲精品| 亚洲国产精品人久久| 国产香蕉久久精品综合网| 久久99精品国产麻豆宅宅| 无码人妻久久一区二区三区蜜桃| 国产成人精品久久二区二区| 亚洲国产日韩欧美久久| 久久青青草原综合伊人| 亚洲国产精品久久电影欧美| 久久久久亚洲?V成人无码| 999久久久免费精品国产| 最新久久免费视频| 欧美性大战久久久久久| 久久久久久久综合日本亚洲| 77777亚洲午夜久久多喷| 污污内射久久一区二区欧美日韩| 94久久国产乱子伦精品免费 | 日本三级久久网| 热re99久久精品国99热| 亚洲国产精品无码成人片久久| 久久人人爽人人人人片av| 四虎国产精品成人免费久久| 久久国产成人| 久久综合亚洲色HEZYO国产| 精品久久久久久无码中文字幕| 国产精品久久久久乳精品爆 | 国产精品免费看久久久香蕉| 精品亚洲综合久久中文字幕| 日本免费一区二区久久人人澡| 久久亚洲国产欧洲精品一|