![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
(1)ハノイの塔とは ハノイの塔とは,重なった円盤を3本柱の間で移動する問題です。 ただし,より小さい円盤が必ず上にくるように重ねます。 たとえば,3枚の円盤の場合,以下のように, 一番左の柱(番号:1)に3枚の円盤があったとします。 これを一番右(番号:3)の柱に移します。 ![]() (2)3枚の場合の手順 たとえば,3枚の場合,次のような手順で1番の柱から3番の柱に移動することができます。 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ここで, ■ (1)から(3)は,2枚の円盤を塔1から塔2に移動する手順, ■ (4)は,最も大きい円盤を塔1から塔3に移動, ■ (5)から(7)は,2枚の円盤を塔2から塔3に移動する手順 です。
(3)N枚の場合の手順 3枚の場合を一般化することを試みましょう。 移動前の塔をA,移動先の塔をB,残りの塔をCとすると, ■ AからCにN−1枚を移動 ■ AからBに1枚を移動 ■ CからBにN−1枚を移動 とすることができます。 ![]() ![]() ![]() ![]() A,Bの組合せに対するCは,次の表の通りとなります。
表に示すとおり, A+B+C=6 の関係が成り立ちますから, C = 6-(A+B) とすることができます。 ![]() ![]() ![]() ![]()
[プログラム例] フォーム上に,textBox1,listBox1,button1を貼り付け, 枚数をtextBox1で指定して,button1をクリックしたら, listBox1に手順が表示されるものとします。 private void MoveTo(int n,int x, int y) { string S=“第”+ n.ToString() + “盤を” + x.ToString() + “軸から” + y.ToString() + "に移動"; listBox1.Items.Add(S); } private void Hanoi(int n, int x, int y) { if(n>0) // 0 枚のときは何もしない { Hanoi(n-1,x, 6-x-y); // n - 1 枚を x → 中間的な塔 MoveTo(n,x,y); // 最も大きい円盤を x → y Hanoi(n-1,6-x-y, y); // n - 1 枚を 中間的な塔 → y } } private void button1_Click(object sender, System.EventArgs e) { listBox1.Items.Clear(); int n = int.Parse(textBox1.Text); Hanoi(n,1,3); } i ![]() ![]() ![]() ![]()
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 上のタイトルをクリックします |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||