Look at the problem first
1- The source of the problem
The pastors of Brahma Church encountered a problem. There is a gold plate with 3 diamond needles on it, one of which has 64 gold plates arranged in order of size. When these priests move a plate every day and follow the original order to move these plates to another needle, time will end. Question: If pastors move a plate every day and they start at year 0, when will time end?
2-Problem refinement:
As shown in the figure below, follow the following three rules to move the plate from the left column to the right column:
(1) After a plate is taken away, it must be put back on a certain column;
(2) Once Only one plate can be moved, and it must be the top one on the column;
(3) Large plates cannot be placed on top of small plates.
3-Problem analysis
Starting from determining an initial state, this situation is very simple: if there is only one plate, then move from the A column to the C column. When there are n plates, in order to move n plates from A to C, the largest plate n must be moved from A to C, so first move the n-1 plates on it to B It can be solved directly by moving the nth plate on the A column directly to the C column. The remaining problem is to move n-1 plates from the B-pillar to the C-pillar, so solving the Tower of Hanoi problem of order n becomes solving the Tower of Hanoi problem of order n-1, the problem is reduced by one order, you can see that this is A recursive problem. The recursive termination condition is n=1, following the steps of order reduction, n=1 must be reached after a finite step, so that the recursive function can be used to solve this problem.
According to the previous analysis, moving the n plates from the A column to the C column can be broken down into the following 3 steps:
(1) Move the n-1 plates on the top of the A column to the B column, and use the C column to transfer;
(2)
Move the remaining plate on the A-pillar to the C-pillar; (3) Move n–1 plates from the B-pillar to the C-pillar, and use the A-pillar to transfer;
these three steps include two operations:
(1) Moving multiple plates from one column to another is a recursive process.
(2) Move 1 plate from one column to another.
Code example
//汉诺塔游戏
#include <iostream>
using namespace std;
int count=0;
void move(char getone,char putone)
{
cout<<getone<<"-->"<<putone<<endl;
count++;
}
void hanot(int n,char A,char B,char C)
{
if(n==1)
move(A,C);
else
{
hanot(n-1,A,C,B); //将第n-1个盘从A移动到B
move(A,C); //将第n个盘从A移动到C
hanot(n-1,B,A,C); //将第n-1个盘从B移动到C
}
}
int main()
{
while(1)
{
int m;
cout<<"输入盘子数:";
cin>>m;
cout<<"移动"<<m<<"个盘的步骤为:"<<endl;
hanot(m,'A','B','C');
cout<<"总共移动的步数为"<<count<<"次"<<endl;
cout<<"------------------------------"<<endl;
}
return 0;
}
Its operating effects are as follows
The main part of the program is that you
might as well take n=2 into it, you can easily understand the program,
but when I take n to 3 or greater, the steps performed by the program will become very large, and the recursion starts to emit Great magic power, successfully made me dizzy. When I wrote the program execution steps on the draft paper until I gave up, I suddenly made an alarm and decided to print out all the program execution steps, as follows:
The code is as follows:
//汉诺塔游戏
#include <iostream>
#include <windows.h>
#include <string.h>
using namespace std;
//设置在控制台打印的字体的颜色,可选white,red,green,blue,yellow,magenta,cyan
void textcolor(char *color)
{
if(!strcmp(color,"white")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
else if(!strcmp(color,"red")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED);
else if(!strcmp(color,"green")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_GREEN);
else if(!strcmp(color,"blue")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_BLUE);
else if(!strcmp(color,"yellow")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
else if(!strcmp(color,"magenta")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);
else if(!strcmp(color,"cyan")) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE);
}
void move(char getone,char putone)
{
textcolor("red");
cout<<getone<<"-->"<<putone<<endl; //在控制台打印出移动步骤为红色
textcolor("cyan");
}
void hanot(int n,char A,char B,char C)
{
cout<<"if("<<n<<"==1)"<<endl;
if(n==1)
{
cout<<"move("<<A<<","<<C<<");"<<endl;
move(A,C);
}
else
{
cout<<"hanot("<<n-1<<","<<A<<","<<C<<","<<B<<");"<<endl;
hanot(n-1,A,C,B); //将第n-1个盘从A移动到B
cout<<"move("<<A<<","<<C<<");"<<endl;
move(A,C); //将第n个盘从A移动到C
cout<<"hanot("<<n-1<<","<<B<<","<<A<<","<<C<<");"<<endl;
hanot(n-1,B,A,C); //将第n-1个盘从B移动到C
}
}
int main()
{
while(1)
{
int m;
textcolor("white");
cout<<"输入盘子数:";
cin>>m;
cout<<"移动"<<m<<"个盘的步骤为红色,程序的执行步骤为青色:"<<endl;
textcolor("cyan");
hanot(m,'A','B','C');
cout<<"------------------------------"<<endl;
}
return 0;
}
Looking at the main part of the function again, is the program execution step clear?