您的位置:首页 > 其它

UVa Problem 10017 - The Never Ending Towers of Hanoi

2012-12-13 19:56 525 查看
[cpp]
view plaincopyprint?

// UVa Problem 10017 - The Never Ending Towers of Hanoi

// Verdict: Accepted

// Submission Date: 2011-11-17

// UVa Run Time: 0.048s

//

// 版权所有(C)2011,邱秋。metaphysis # yeah dot net

//

// [解题方法]

// 经典汉诺塔问题的一个变形吧,加了显示当前柱子圆盘状态的要求。题解使用 bool 数组来表示圆盘是否在

// 某根柱子上,因为有小圆盘总是在大圆盘上面的限制,只需记录某根柱子有哪些圆盘,在输出时,按从大到小

// 的顺序输出圆盘序号即可。

#include <iostream>

using namespace std;

#define A 1

#define B 2

#define C 3

#define MAXDISKS 251

#define MAXPEGS 4

int nDisks, nLastMove, steps;
bool pegs[MAXPEGS][MAXDISKS], stepsReached;

// 显示柱子的圆盘状态。

void printStatus()
{
if (steps > nLastMove)
{
stepsReached = true;
return;
}

for (int i = A; i <= C; i++)
{
cout << (char) ('A' + i - 1) << "=>";

bool printSpace = false;
for (int j = nDisks; j >= 1; j--)
if (pegs[i][j])
{
if (printSpace == false)
{
cout << " ";
printSpace = true;
}

cout << " " << j;
}

cout << "\n";
}

cout << "\n";

steps++;
}

// 移动圆盘并显示。

void move(int n, int from, int middle, int to)
{
pegs[from]
= false;
pegs[to]
= true;

printStatus();
}

// 递归实现汉诺塔移动。

void hanoi(int n, int from, int middle, int to)
{
if (stepsReached)
return;

if (n == 1)
{
move(n, from, middle, to);
return;
}
else
{
hanoi(n - 1, from, to, middle);
move(n, from, middle, to);
hanoi(n - 1, middle, from, to);
}
}

int main(int argc, char const *argv[])
{
int cases = 1;

while (cin >> nDisks >> nLastMove, nDisks || nLastMove)
{
cout << "Problem #" << cases++ << "\n\n";

steps = 0;
stepsReached = false;

for (int i = 1; i < MAXPEGS; i++)
for (int j = 1; j <= nDisks; j++)
pegs[i][j] = false;
for (int i = 1; i <= nDisks; i++)
pegs[1][i] = true;

printStatus();

hanoi(nDisks, A, B, C);
}

return 0;
}

// UVa Problem 10017 - The Never Ending Towers of Hanoi
// Verdict: Accepted
// Submission Date: 2011-11-17
// UVa Run Time: 0.048s
//
// 版权所有(C)2011,邱秋。metaphysis # yeah dot net
//
// [解题方法]
// 经典汉诺塔问题的一个变形吧,加了显示当前柱子圆盘状态的要求。题解使用 bool 数组来表示圆盘是否在
// 某根柱子上,因为有小圆盘总是在大圆盘上面的限制,只需记录某根柱子有哪些圆盘,在输出时,按从大到小
// 的顺序输出圆盘序号即可。

#include <iostream>

using namespace std;

#define A 1
#define B 2
#define C 3

#define MAXDISKS 251
#define MAXPEGS 4

int nDisks, nLastMove, steps;
bool pegs[MAXPEGS][MAXDISKS], stepsReached;

// 显示柱子的圆盘状态。
void printStatus()
{
if (steps > nLastMove)
{
stepsReached = true;
return;
}

for (int i = A; i <= C; i++)
{
cout << (char) ('A' + i - 1) << "=>";

bool printSpace = false;
for (int j = nDisks; j >= 1; j--)
if (pegs[i][j])
{
if (printSpace == false)
{
cout << "  ";
printSpace = true;
}

cout << " " << j;
}

cout << "\n";
}

cout << "\n";

steps++;
}

// 移动圆盘并显示。
void move(int n, int from, int middle, int to)
{
pegs[from]
= false;
pegs[to]
= true;

printStatus();
}

// 递归实现汉诺塔移动。
void hanoi(int n, int from, int middle, int to)
{
if (stepsReached)
return;

if (n == 1)
{
move(n, from, middle, to);
return;
}
else
{
hanoi(n - 1, from, to, middle);
move(n, from, middle, to);
hanoi(n - 1, middle, from, to);
}
}

int main(int argc, char const *argv[])
{
int cases = 1;

while (cin >> nDisks >> nLastMove, nDisks || nLastMove)
{
cout << "Problem #" << cases++ << "\n\n";

steps = 0;
stepsReached = false;

for (int i = 1; i < MAXPEGS; i++)
for (int j = 1; j <= nDisks; j++)
pegs[i][j] = false;
for (int i = 1; i <= nDisks; i++)
pegs[1][i] = true;

printStatus();

hanoi(nDisks, A, B, C);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: