main函數(shù)中輸入移動(dòng)漢諾塔的個(gè)數(shù),最多不超過10個(gè)
#include<stdlib.h>
#include<stdio.h>
#include<Windows.h>
int a[10][3]={0};
void hannuo(int n,char A,char B,char C);//移動(dòng)的過程
void show(int a[10][3]);//顯示的作用
void move(char X,char Y);//移動(dòng),鏈接數(shù)據(jù)到視圖
int main()
{
int n=0;
scanf("%d",&n);
for(int i=0;i<n;i++) //布局
{
a[10-1-i][0]=n-i;//操作第一列 循環(huán)操作行, 第一行就是10-1,第i行就是10-1-i
}
show(a);//傳遞a
Sleep(1000);
hannuo(n,'A','B','C');
return 0;
}
void show(int a[10][3])
{
printf("%5c%5c%5c\n",'A','B','C');
printf("---------------------\n");//分隔符
for(int i=0;i<10;i++)//顯示
{
for(int j=0;j<3;j++)
{
printf("%5d",a[i][j]);//遍歷輸出現(xiàn)在的狀態(tài)
}
printf("\n"); // 輸出一行就 換行
}
}
void hannuo(int n,char A,char B,char C)
{
//A B C
//0
//1
//2
//2 1
// 1 2
// 1
// 2
//以上是兩個(gè)漢諾塔的移動(dòng)過程,如果是三個(gè)
//1
//2
//3
//把1,2綁定起來作為一柠并,3作為二,那么遞歸調(diào)用上層兩個(gè)漢諾塔的移動(dòng)成玫,算法就實(shí)現(xiàn)三個(gè)
//N個(gè)移動(dòng)要調(diào)用第N-1個(gè)移動(dòng),通過遞歸實(shí)現(xiàn)
if(n<1)
{
return;
}
else if(n==1)
{
printf("\n%c->%c\n",A,C); // move函數(shù)做好了再做下一步绿渣,這一步只是說要移動(dòng)的東西
move(A,C);
show(a);
}//簡單的情況考慮了 下面來復(fù)雜的
else
{
//N個(gè)漢諾
//A B C
//N-1
//N
//N N-1 第一步N-1從A移動(dòng)到B
// N-1 N
// N-1
// N
hannuo(n-1,A,C,B);//A->B 遞歸,由于最簡單的情況他只能執(zhí)行A與C的交換根灯,所以這里把A,B放入A,C的位置
Sleep(1000);
printf("\n%c->%c\n",A,C);//直接移動(dòng)A到C
Sleep(1000);
move(A,C);
Sleep(1000);
show(a);
Sleep(1000);
hannuo(n-1,B,A,C);//B移動(dòng)到C
}
}
void move(char X,char Y)
{ //A B C
//0
//1
//2
//3
//4 0
// 0與1交換
//0
//0
//2
//3
//4 1
int m=X-65;//[9][m] A---- m=0
int n=Y-65;//[9][n] C---- n=2
int imove=-1;//找到第一個(gè)不為0的數(shù)径缅,即為第一個(gè)漢諾塔盤片
for (int i=0;i<10;i++)
{
if(a[i][m]!=0)
{
imove=i;
break;//找到第一個(gè)不為0的數(shù)
}
}
//需要的移動(dòng)a[imove][m]
//找到a[jmove][n]
int jmove;
if(a[9][n]==0)//最后一個(gè)為0
{
jmove=9;
}
else
{
jmove=10;
for(i=0;i<10;i++)
{
if(a[i][n]!=0)//檢索第一個(gè)不為0
{
jmove=i; // 與檢測imove第一個(gè)不為0的數(shù)一樣,但是要移動(dòng)的是這個(gè)不為0上面的0
break;
}
}
jmove-=1;
}
int temp=a[imove][m];
a[imove][m]=a[jmove][n];
a[jmove][n]=temp;
}