1. 程式人生 > >新漢諾塔

新漢諾塔

找到 格式 adg void region 大盤 dfs names -o

題目描述

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

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

移動時有如下要求:

·一次只能移一個盤;

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

輸入輸出格式

輸入格式:

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

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

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

輸出格式:

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

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

輸入輸出樣例

輸入樣例#1: 復制
5
3 3 2 1
2 5 4
0
1 2
3 5 4 3
1 1
輸出樣例#1: 復制
move 1 from A to B
move 2 from A to C
move 1 from B to C
move 3 from A to B
move 1 from C to B
move 2 from C to A
move 1 from B to C
7

說明

圓盤總數≤45

首先要將第n個盤子從x到y

那麽就要把比n小的盤子全部移到6-x-y

遞歸處理

然後將n移到y

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int a[101],b[101],n;
 7 long long ans;
 8 void dfs(int x,int des)
 9 {int i;
10     if (a[x]==des) return;
11     for (i=x-1;i>=1;i--)
12     dfs(i,6
-des-a[x]); 13 printf("move %d from %c to %c\n",x,a[x]+64,des+64); 14 a[x]=des;ans++; 15 } 16 int main() 17 {int x,i,d; 18 cin>>n; 19 cin>>x; 20 for (i=1;i<=x;i++) 21 {scanf("%d",&d);a[d]=1;} 22 cin>>x; 23 for (i=1;i<=x;i++) 24 {scanf("%d",&d);a[d]=2;} 25 cin>>x; 26 for (i=1;i<=x;i++) 27 {scanf("%d",&d);a[d]=3;} 28 29 cin>>x; 30 for (i=1;i<=x;i++) 31 {scanf("%d",&d);b[d]=1;} 32 cin>>x; 33 for (i=1;i<=x;i++) 34 {scanf("%d",&d);b[d]=2;} 35 cin>>x; 36 for (i=1;i<=x;i++) 37 {scanf("%d",&d);b[d]=3;} 38 39 for (i=n;i>=1;i--) 40 dfs(i,b[i]); 41 cout<<ans; 42 }

新漢諾塔