判斷一個M*N的國際象棋馬跳圖是否有漢密頓迴路

                 最近上了算法課,寫了一個判斷M*N的馬跳圖中,是否存在漢密頓迴路。用的是完全遍歷的方法,這裏沒有使用遞歸的方法,一直遍歷圖中的路徑節點,直到找到一條滿足條件漢密頓迴路則停止,當然,這樣的算法效率比較低,特別是圖中沒有漢密頓迴路時,要遍歷所有可能的路徑。

希望與大家共同學習,共同進步

後續會寫一個用分支限界來判定的方法。。。敬請期待!

#include<stdio.h>
#define M  6                             //行數
#define N  6                            //列數

int islegal(int x, int y);

void main(void)
{
	int flag[M][N];                          //標註是否走過
	int route[M*N][8];                       //標註每個方向的路徑是否可走,0爲不可走,1爲可走
	
//標記每一步的前一步的行和列	
	int fromcol[M*N]={0};                          
	int fromrow[M*N]={0};
	
	int direct[][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}}; //每步可以走的八個方向

    int curcol=-1;                       //當前行
	int currow=-1;                       //當前列
	
	int nextcol=-1;                      //下一行
	int nextrow=-1;                      //下一列  

// 初始化flag
	int i,j;
	for(i=0;i<M;i++)
	{
		for(j=0;j<N;j++)
		{
			flag[i][j]=0;
		}
	}


//初始化route
	int k;
	int pos;                              //當前在數組中的位置
	for(curcol=0; curcol<M; curcol++)
	{
		
		for(currow=0; currow<N; currow++)
		{
			pos=curcol*N+currow;
			for(k=0; k<8; k++)
			{
				nextcol=curcol+direct[k][0];
				nextrow=currow+direct[k][1];
				if(islegal(nextcol,nextrow))
				{
					route[pos][k]=1;
				}
				else
				{
					route[pos][k]=0;
				}
			}
		}
	}


 //回溯遍歷尋找路徑
	curcol=0;
	currow=0;
	pos=0;
	int num=1;
	while(num<=M*N)                                                 //當又回到原點時結束
	{
		
		for(i=0;i<8;i++)                                 //尋找下一個合適的步
		{
			nextcol=curcol+direct[i][0];
			nextrow=currow+direct[i][1];
			
			if(nextcol==0 && nextrow==0 && num==M*N)
			{
				num++;      //爲了退出循環
				break;
			}
			if(islegal(nextcol,nextrow) && flag[nextcol][nextrow]==0)
			{
				if(route[pos][i])
				{
					flag[curcol][currow]=1;
					route[pos][i]=0;                          //防止回溯時走已走過的路

					curcol=nextcol;
					currow=nextrow;
 					pos=curcol*N+currow;
					fromcol[pos]=curcol-direct[i][0];        //保存前一個點的位置
					fromrow[pos]=currow-direct[i][1];
					num++;
					break;
				}
			}
		}
		
		if(i==8)                                           //沒有找到合適的步,進行回溯
		{
			if(flag[curcol][currow]==1)
			{
				flag[curcol][currow]=0;
				
			}
			
			pos=curcol*N+currow;

			for(j=0; j<8; j++)               //恢復退出的節點
			{
				if(islegal(curcol+direct[j][0],currow+direct[j][1]) && route[pos][j]==0)
				{
					route[pos][j]=1;
				}
			}
			curcol=fromcol[pos];
			currow=fromrow[pos];
			pos=curcol*N+currow;
 			
			num--;
			if(num==0)break;
		
		}
	}
	printf("%d\n",num);
	printf("%d,%d",curcol,currow);
	if(num==0)
	{
		printf("無  漢密頓迴路\n");
	}
	else if(num==M*N+1)
	{
		printf("有  漢密頓迴路\n");
	}

}

// 所在位置合法是返回值爲1;否則返回0
int islegal(int x, int y)
{
	if((x>=0 && x<M) && (y>=0 && y<N))return 1;
	else
	{
		return 0;
	}
}


發佈了21 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章