日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P1242 新汉诺塔

發布時間:2023/12/10 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P1242 新汉诺塔 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

設有n個大小不等的中空圓盤,按從小到大的順序從1到n編號。將這n個圓盤任意的迭套在三根立柱上,立柱的編號分別為A、B、C,這個狀態稱為初始狀態。

現在要求找到一種步數最少的移動方案,使得從初始狀態轉變為目標狀態。

移動時有如下要求:

·一次只能移一個盤;

·不允許把大盤移到小盤上面。

輸入輸出格式

輸入格式:

文件第一行是狀態中圓盤總數;

第二到第四行分別是初始狀態中A、B、C柱上圓盤的個數和從上到下每個圓盤的編號;

第五到第七行分別是目標狀態中A、B、C柱上圓盤的個數和從上到下每個圓盤的編號。

?

輸出格式:

每行一步移動方案,格式為:move I from P to Q

最后一行輸出最少的步數。

思路:

只有三個柱子,每次把一個柱子上面的圓盤都移到除該柱子和目標柱外的另一個柱子,

當然,要從最大的一個圓盤開始移動。

代碼解釋:

#include<iostream> using namespace std; int from[55],to[55],ans,n,t,m; void dfs(int x,int y)//x代表第x大的圓盤,y代表移到第y個柱子上 {if(from[x]==y)return ;//如果圓盤已經在目標位置上了,就不需要再移動了for(int l=x-1;l>0;l--)//也要從大到小移動dfs(l,6-from[x]-y);cout<<"move"<<' '<<x<<' '<<"from"<<' '<<char(from[x]+'A'-1)<<' '<<"to"<<' '<<char(y+'A'-1)<<endl;from[x]=y;ans++; //于是更新第x大的圓盤的位置 } int main() {cin>>m;cin>>n;for(int i=1;i<=n;i++)cin>>t,from[t]=1;cin>>n;for(int i=1;i<=n;i++)cin>>t,from[t]=2;cin>>n;for(int i=1;i<=n;i++)cin>>t,from[t]=3;cin>>n;for(int i=1;i<=n;i++)cin>>t,to[t]=1;cin>>n;for(int i=1;i<=n;i++)cin>>t,to[t]=2;cin>>n;for(int i=1;i<=n;i++)cin>>t,to[t]=3;//夸張的讀入QAQfor(int i=m;i>0;i--)//從最大的柱子開始移動,畢竟大柱子要放在底下dfs(i,to[i]);cout<<ans; return 0; }

PS:

有這樣一組數據:

3 1 3 0 2 2 1 2 2 1 0 1 3

按照曾經AC的程序,面對這樣的數據,我們會先努力把圓盤?3 移動到 C?柱上。

所以我們的代碼先移動了?1,2兩個圓盤到?B柱,再把 3?這個圓盤從?A干脆利落地移動到 C?……

move 1 from C to A move 2 from C to B move 1 from A to B move 3 from A to C move 1 from B to C move 2 from B to A move 1 from C to A 7

然而以上不是最優解。下面才是:

move 3 from A to B move 1 from C to B move 2 from C to A move 1 from B to A move 3 from B to C 5

可見我們的代碼忽略了空柱的作用,誤以為“必須一步把當前要移動的最大圓盤移動到目標柱子”(比如需要移動把圓盤?3從?A移到?C ,我們想盡辦法把 A?和?C 兩個柱子上小于?3的圓盤都移到?B )。

原因是,我們的代碼已知?3是最大的圓盤,也就是其它圓盤都比它小。如果先移動它到沒有清空的柱子上,我們擔心它會壓到小盤上,這樣就不符合規則了。而在最優解中,他先把圓盤?3移動到?B 柱(因為?B 是空柱,所以我們白白擔心了)。這樣,接下來移動?1,2兩個圓盤時就直接到了它們的目的地:?A柱。

我現在除了特判還沒想到別的:

? if(m==3&&n==1&&to[3]==3) {cout<<"move 3 from A to B"<<endl;cout<<"move 1 from C to B"<<endl;cout<<"move 2 from C to A"<<endl;cout<<"move 1 from B to A"<<endl;cout<<"move 3 from B to C"<<endl;cout<<5; }?

Over

轉載于:https://www.cnblogs.com/qkmqkm/p/9342959.html

總結

以上是生活随笔為你收集整理的P1242 新汉诺塔的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。