桌子上有一疊盤子,桌子上只能同時放三疊盤子,小的盤子只能放在大的盤子上,為了不打碎盤子,一次只能移動一個,盤子從左邊最快地移動到右邊,請問在移動盤子時,某些情形是否可能出現?
n個盤子從左邊最快移動到右邊等價於
前n-1個盤子從左邊最快移動到中間
第n個盤子從左邊最快移動到右邊
前n-1個盤子從中間最快移動到右邊
n個盤子從左邊最快移動到右邊時,某些情形是否可能出現等價於
第n個盤子在左邊時,前n-1個盤子從左邊最快移動到中間時這些情形是否可能出現
第n個盤子在右邊時,前n-1個盤子從中間最快移動到右邊時這些情形是否可能出現
先量化
1
3 2
5 4
8 7 6
運行
How many dishes do you have?
8
How many dishes in the left?
4
Whats the sequence of the dishes?
8 5 3 1
How many dishes in the middle?
3
Whats the sequence of the dishes?
7 4 2
How many dishes in the right?
1
Whats the sequence of the dishes?
6
Wait a minute.
What a pity!
//Copyright (c) LeafCore
#include <iostream>
using namespace std;
//盤子數量
const int const_m=64;
//存放盤子次序
int dish[3][const_m];
//指向最底端的盤子
int bottom[3];
//n個盤子從from移動到to時情形是否可能出現
bool possible(int n, int from, int to)
{
//遞歸出口,只有一個盤子從from移動到to時情形是否可能出現
if (n==1) {
if (dish[from][bottom[from]]==1 || dish[to][bottom[to]]==1) {
return true;
} else {
return false;
}
}
//最大的盤子在左邊
if (dish[from][bottom[from]]==n) {
//跳過最大的盤子
bottom[from]++;
//前n-1個盤子從from移動到from及to以外的另一個位置時情形是否可能出現
return possible(n-1, from, 3-from-to);
}
//最大的盤子在右邊
if (dish[to][bottom[to]]==n) {
//跳過最大的盤子
bottom[to]++;
//前n-1個盤子從from及to以外的另一個位置移動到to時情形是否可能出現
return possible(n-1, 3-from-to, to);
}
return false;
}
int main()
{
int m, n;
while (true) {
//輸入盤子數量
cout<<"How many dishes do you have?"<<endl;
cin>>n;
for (int i=0; i<3; i++) {
//輸入每個位置盤子數量
cout<<"How many dishes in the "<<(i==0?"left":(i==1?"middle":"right"))<<"?"<<endl;
cin>>m;
//輸入盤子序列
cout<<"Whats the sequence of the dishes?"<<endl;
for (int j=0; j<m; j++) {
cin>>dish[i][j];
}
//指向最底端的盤子
bottom[i]=0;
}
cout<<"Wait a minute."<<endl;
//輸出結果
cout<<(possible(n, 0, 2)?"Awesome!":"What a pity!")<<endl;
getchar();
getchar();
}
return 0;
}