馬踏棋盤(棧實現)

peter_linky發表於2014-10-18

馬踏棋盤演算法:

原理:國際象棋的棋盤為8*8的方格棋盤。現將"馬"放在任意指定的方格中,按照"馬"走棋的規則將"馬"進行移動。要求每個方格只能進入一次,最終使得"馬"走遍棋盤的64個方格。

/*實現步驟:
 * 定義一個二維陣列Chess[N][N],並將其初始化為0.用來表示棋盤
 * 輸出二維陣列,選擇開始得座標,將座標入棧,令其對應位置=count(踏過得順序)
 * 判斷以其為中心的八個位置是否可以跳,
 * 若可以,按自定義的位置順序選擇下一次跳哪一個,將其座標入棧,對應位置=count
 * 若不可以,彈棧,判斷以前一個座標為中心的是否還有位置可跳。
 * 直到陣列每一個元素不為0為止(while迴圈)
 */

以下為程式程式碼:

#include<stdio.h>
#include<stdlib.h>
#define FALSE 0
#define TRUE 1
#define OK 1
#define ERROR 0
#define MAXSIZE 100
#define N 10
typedef int ElemType;
typedef struct node
{
	struct test
	{
		ElemType cow;		//儲存行值
		ElemType low;		//儲存列值
	}data[MAXSIZE];
	ElemType top;			//top——棧頂
}SeqStack;

static int count=1;			//count用來記錄跳過的位置。從一開始

void Print(int Chess[N][N]);
int Next_Run(int *c,int *l, int Chess[N][N]);

SeqStack *Init()
{
	/*初始化:top=-1*/
	SeqStack *s;

	s=(SeqStack*)malloc(sizeof(SeqStack));
	s->top=-1;
	return s;

}


int IsEmpty(SeqStack *s)
{
	/*判斷棧是否為空*/
	if(s->top == -1)
		return TRUE;
	else
		return FALSE;
}

int Push(SeqStack *s, int c, int l)
{
	/*入棧操作*/
	if(s->top == MAXSIZE -1)
	{
		printf("桟已滿,不能入棧\n");
		return FALSE;
	}
	s->top++;
	s->data[s->top].cow=c;
	s->data[s->top].low=l;

	return TRUE;
}

int Pop(SeqStack *s, int *c, int *l)
{
	/*出棧操作*/
	if(IsEmpty(s))
	{
		printf("棧為空,不能出棧\n");
		return FALSE;

	}
	s->top--;
	*c=s->data[s->top].cow;
	*l=s->data[s->top].low;
	return TRUE;
}

int GetTop(SeqStack *s)
{
	/*獲取棧頂元素*/
	if(IsEmpty(s))
	{
		printf("棧為空,不能取棧頂元素\n");
		return FALSE;

	}
	return s->data[s->top].low;

}
//以上均為棧的相關操作


int main(void)
{
	SeqStack *Q;
	Q = Init();			//初始化棧

	int Chess[N][N] = {0};		//用二位陣列表示棋盤
	//int i, j;
	int c, l;			//c代表行,l代表列

	Print(Chess);			//輸出棋盤


	printf("請選擇初始位置(幾行幾列)\n");
	scanf("%d%d", &c, &l);		//輸入起始位置

	if(Judge(c, l))
	{				//判斷起始位置合法性
		printf("起始位置不合法\n");
		exit(1);
	}

	Push(Q, c, l);			//將起始位置入棧
	Chess[c][l] = count;		//陣列對應值變化為count
	count++;			//count++
	Print(Chess);			//列印棋盤

	while(count != N*N+2)		//用count迴圈判斷是否跳完。
	{
		if(Next_Run(&c,&l,Chess))			//判斷下一個跳得位置
		{						//若可以,將其座標入棧
			Push(Q, c, l);
			Chess[c][l]=count;			//陣列對應位置變化
			count++;
			system("clear");
			Print(Chess);

		}
		else						//否則,將該座標出棧,
								//判斷上一個座標是否可以
		{
			Pop(Q, &c,&l);

		}
	}

	return 0;
}


int Next_Run(int *c, int *l, int Chess[N][N])
{							//判斷是否存在可以跳的位置
	if(*c-2 >= 0 && *l-1 >= 0 && Chess[*c-2][*l-1]==0)	//若存在,返回1;
							//否則,返回0;
	{
		*c-=2;
		*l-=1;
		return 1;
	}
	else if(*c-2 >= 0 && *l+1 <= N-1 && Chess[*c-2][*l+1]==0)
	{
		*c-=2;
		*l+=1;
		return 1;
	}
	else if(*c-1 >=0 && *l-2 >=0 && Chess[*c-1][*l-2]==0)
	{
		*c-=1;
		*l-=2;
		return 1;
	}
	else if(*c-1 >=0 && *l+2 <=N-1  && Chess[*c-1][*l+2]==0)
	{
		*c-=1;
		*l+=2;
		return 1;
	}
	else if(*c+2 <= N-1 && *l-1 >=0  && Chess[*c+2][*l-1]==0)
	{
		*c+=2;
		*l-=1;
		return 1;
	}
	else if(*c+2 <= N-1 && *l+1 <= N-1  && Chess[*c+2][*l+1]==0)
	{
		*c+=2;
		*l+=1;
		return 1;
	}
	else if(*c+1 <= N-1 && *l-2 >= 0  && Chess[*c+1][*l-2]==0)
	{
		*c+=1;
		*l-=2;
		return 1;
	}
	else if(*c+1 <= N-1 && *l+2 >=0  && Chess[*c+1][*l+2]==0)
	{
		*c+=1;
		*l+=2;
		return 1;
	}

	return 0;

}


void Print(int Chess[N][N])
{							//列印棋盤
	int i;
	int j;

	for(i=0; i<N; i++)
	{
		for(j=0; j<N; j++)
		{
			printf("%5d", Chess[i][j]);
		}

		printf("\n");
	}
}

int Judge(int c, int l)
{							//判斷起始位置是否合法
	if(c>N-1 || l>N-1)
		return 1;
	return 0;
}

程式效果圖:


相關文章