在一个塔座上有一叠大小不等的共n 个圆盘。各圆盘从小到大编号为1,2,……,n。
初始时,这些圆盘自下而上散乱地叠在一起。现要求按照以下翻转规则,经若干次翻转,将
塔座上的这一叠圆盘排好序,即按自底向上,从大到小的顺序叠置。
翻转规则:每次可以将最顶上的若干圆盘翻转,即按其相反的次序叠置。
例如,在下面的 3个圆盘叠置状态中,中间状态是在左边状态中第3 个圆盘以上所有圆
盘翻转后得到的,相应翻转记为flip(3);右边状态是将中间状态中第1个圆盘以上所有圆
盘翻转得到的,相应翻转记为flip(1)。
8 7 2
4 6 5
6 4 8
7 8 4
5 5 6
2 2 7
´实验任务:
对于给定的大小不等的n个圆盘的初始状态,用翻转运算将n 个圆盘排序。
´数据输入:
由文件input.txt给出输入数据。第 1 行是给定的圆盘自顶向下的初始状态。
´结果输出:
将排序所用的翻转运算依次输出到文件 output.txt。输出翻转运算flip(i)时,只要输出数
字i即可,相邻数字用空格分隔。
输入文件示例 输出文件示例
input.txt output.txt
5 1 2 3 4 1 2
简单起见我就以0作为输入结束。这个算法的思想和朴素汉诺塔还是有点像的,朴素汉诺塔的思想是先将(n-1)块圆盘从A->B,然后将最大的那块从A->C,再把这(n-1)块从B->C,当然这(n-1)块不可能一次性移动,这就需要递归了
#include <cstdio>
int cnt = 0;
void Hanoi(int n = 5, char A = 'A', char B = 'B', char C = 'C')
{
if( n == 1 ){
printf("%c->%c\n", A, C);
cnt++;
}else{
Hanoi(n-1, A, C, B); //(n-1)块A->B
Hanoi(1, A, B, C); // 1块A->C
Hanoi(n-1, B, A, C); //(n-1)块B->C
}
}
int main()
{
Hanoi();
printf("cnt = %d\n", cnt);
return 0;
}
而这个翻转汉诺塔问题的思想就是,在塔(数组或者容器)中找到最大圆盘(值),想办法将其翻转至相对最下方。因为塔只能将上方的圆盘翻转,因此需要将该圆盘先翻转至最高处,再从最高处翻转至相对最低处(之所以说相对是因为随着翻转进行比这个值更大的已经在塔底了)
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
vector<int> data;
void init_Data()
{
int x;
vector<int>().swap(data);
// 以0代表结束
while( scanf("%d",&x) && x!=0 )
data.push_back(x);
}
bool isOver()
{
for(int i = 1; i < data.size(); ++i)
if( data[i] < data[i-1] )
return false;
return true;
}
void reverse(int m, int n)
{
int t;
while( m < n ){
t = data[m];
data[m] = data[n];
data[n] = t;
++m, --n;
}
}
void reverse_Hanoi()
{
int max, maxIndex, pos = 0;
int n = data.size(), size = data.size();
while( n-- )
{
// 判断是否结束
if( isOver() )
return;
maxIndex = 0, max = data[0];
// 找到相对最大值
for(int i = 0; i < size-pos; ++i)
if( data[i] > max ){
max = data[i];
maxIndex = i;
}
// 若相对最大值在相对最底部,无需操作,否则
if( maxIndex != size-pos-1 ){
// 若相对最大值已经在最高层,无需翻转
if( maxIndex != 0 ){
// 否则先将相对最大值翻转到最高层
reverse(0, maxIndex);
printf("%d ", size-maxIndex);
}
// 再将相对最大值翻转到相对最底部
reverse(0, size-pos-1);
printf("%d ", pos+1);
}
pos++;
}
}
int main()
{
init_Data();
reverse_Hanoi();
return 0;
}