码迷,mamicode.com
首页 > 其他好文 > 详细

Hanio问题

时间:2016-04-17 18:06:25      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:hanio

假设有三个命名为 A B C 的塔座 ,在塔座A上插有n个直径大小不相同,由小到大编号为1 ,2 ,3 ,··· ,n的圆盘,要求将A座上的圆盘移至塔座C,并按同样的顺序叠排

圆盘移动必须遵守下列规则:

1:每次只能移动一个圆盘 

2:圆盘可以插在任意一个塔座上 

3:任何时刻都不能将一个较大的圆盘放在一个较小的圆盘上

该问题的复杂性:

若有n个盘子,則移动完所需之次数为2^n - 1,

//递归打印移动图像
//开始
//1 0 0
//2 0 0
//3 0 0
//达到
//0 0 1
//0 0 2
//0 0 3
#define N 4//目前盘子数
int array[N][3];//n行3列表示柱子
int Count[3];//存储当前应该访问下标,n表示不可访问
void Init()
{
	int num = 1;
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < 3; j++)
		{
			if (j == 0)
				array[i][j] = num++;
			else
				array[i][j] = 0;
		}
	}
	Count[0] = 0;
	Count[1] = N;
	Count[2] = N;
}
void Print()
{
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < 3; j++)
		{
			printf("%d ", array[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}
void Swap(int &num1, int & num2)
{
	num2 = num1;
	num1 = 0;
}
void hanio(int n, int a, int b, int c)
{
	if (n == 1)
	{
		Swap(array[Count[a]][a], array[Count[c] - 1][c]);
		Count[a]++;
		Count[c]--;
		Print();
		return;
	}
	hanio(n - 1, a, c, b);
	Swap(array[Count[a]][a], array[Count[c] - 1][c]);
	Count[a]++;
	Count[c]--;
	Print();
	hanio(n - 1, b, a, c);
}

void Test1()
{
	Init();
	Print();
	hanio(N, 0, 1, 2);
}
//非递归
#pragma once
#include<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;
#define N 64
class Stack
{
public:
	Stack()
	:_top(-1)
	{
		for (int i = 0; i < N; ++i)
			_array[i] = 0;
	}
	void Push(int x)
	{
		_array[++_top] = x;
	}
	void Pop()
	{
		assert(_top != -1);
		_top--;
	}
	int Top()
	{
		assert(_top != -1);
		return  _array[_top];
	}
	bool IsEmpty()
	{
		return _top == -1;
	}
	char& GetName()
	{
		return _name;
	}
protected:
	int _top;
	int _array[N];
	char _name;
};
void Create(Stack s[], int n)
{
	s[0].GetName() = ‘A‘;
	if (n % 2 == 0)
	{
		(s[1]).GetName() = ‘B‘;
		(s[2]).GetName() = ‘C‘;
	}
	else
	{
		(s[1]).GetName() = ‘C‘;
		(s[2]).GetName() = ‘B‘;
	}
	for (int i = 0; i < n; ++i)
	{
		s[0].Push(n - i);
	}
}
void Hanio(Stack s[], int max)
{
	int steps = 0;
	int i = 0;
	int ch;
	while (steps < max)
	{
		ch = s[i % 3].Top();
		s[(i + 1) % 3].Push(ch);
		s[i % 3].Pop();
		cout << "(" << ++steps << "): " << ch << " from " << s[i % 3].GetName() << " to " << s[(i + 1) % 3].GetName()
			<< endl;
		++i;
		if (steps < max)
		{
			if (s[(i + 1) % 3].IsEmpty() == true || s[(i - 1) % 3].IsEmpty() == false &&s[(i + 1) % 3].Top() > s[(i - 1) % 3].Top())
			{
				ch = s[(i - 1) % 3].Top();
				s[(i + 1) % 3].Push(ch);
				s[(i - 1) % 3].Pop();
				cout << "(" << ++steps << "): " << ch << " from " << s[(i - 1) % 3].GetName() << " to " << s[(i + 1) % 3].GetName()
					<< endl;
			}
			else
			{
				ch = s[(i + 1) % 3].Top();
				s[(i - 1) % 3].Push(ch);
				s[(i + 1) % 3].Pop();
				cout << "("<< ++steps << "): " <<ch << " from " << s[(i + 1) % 3].GetName() << " to " << s[(i -1) % 3].GetName()
					<< endl;
			}
		}
	}
}
void Test1()
{
	Stack s[3];
	int n;
	cout << "please input :" << endl;
	cin >> n;
	Create(s, n);
	int max = pow(2, n) - 1;
	Hanio(s, max);
}

运行结果,输入4

技术分享

本文出自 “小止” 博客,请务必保留此出处http://10541556.blog.51cto.com/10531556/1764703

Hanio问题

标签:hanio

原文地址:http://10541556.blog.51cto.com/10531556/1764703

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!